Type not defined after registering with qmlRegisterSingletonInstance
-
I have a minimum (not) working example copied from the documentation regarding
qmlRegisterSingletonInstance.
It looks like the following:
//main.cpp #include <QGuiApplication> #include <QQmlApplicationEngine> #include <singletontypeexample.hpp> int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); QQmlApplicationEngine engine; auto* singletonInstance = new SingletonTypeExample(&app); qmlRegisterSingletonInstance("SingletonInstance", 1, 0, "_singletonInstance", singletonInstance); QObject::connect( &engine, &QQmlApplicationEngine::objectCreationFailed, &app, []() { QCoreApplication::exit(-1); }, Qt::QueuedConnection); engine.loadFromModule("QMLPlayground", "Main"); return app.exec(); }
// singletontypeexample.hpp #pragma once #include <QObject> class SingletonTypeExample : public QObject { Q_OBJECT Q_PROPERTY(int someProperty READ someProperty WRITE setSomeProperty NOTIFY somePropertyChanged) public: explicit SingletonTypeExample(QObject* parent = nullptr) : QObject(parent) {} Q_INVOKABLE int doSomething() { setSomeProperty(5); return m_someProperty; } int someProperty() const { return m_someProperty; } void setSomeProperty(int val) { if (m_someProperty != val) { m_someProperty = val; emit somePropertyChanged(val); } } signals: void somePropertyChanged(int newValue); private: int m_someProperty = 0; };
// singletontypeexample.cpp #include "singletontypeexample.hpp"
// Main.qml import QtQuick import QtQuick.Controls import QtQuick.Layouts import SingletonInstance 1.0 Window { width: 3000 height: 1800 visible: true Component.onCompleted: { console.error(_singletonInstance.doSomething()); } }
#CMakeLists.txt cmake_minimum_required(VERSION 3.16) project(QMLPlayground VERSION 0.1 LANGUAGES CXX) set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) qt_standard_project_setup(REQUIRES 6.5) qt_add_executable(appQMLPlayground main.cpp singletontypeexample.hpp singletontypeexample.cpp ) qt_add_qml_module(appQMLPlayground URI QMLPlayground VERSION 1.0 QML_FILES Main.qml ) # Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1. # If you are developing for iOS or macOS you should consider setting an # explicit, fixed bundle identifier manually though. set_target_properties(appQMLPlayground PROPERTIES # MACOSX_BUNDLE_GUI_IDENTIFIER com.example.appQMLPlayground MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} MACOSX_BUNDLE TRUE WIN32_EXECUTABLE TRUE ) target_link_libraries(appQMLPlayground PRIVATE Qt6::Quick ) include(GNUInstallDirs) install(TARGETS appQMLPlayground BUNDLE DESTINATION . LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} )
I try to instantiate the singleton type and use it in qml, but I get
qrc:/qt/qml/QMLPlayground/Main.qml:12: ReferenceError: _singletonInstance is not defined
.
I have no clue what I am doing wrong. Do you have a hint?
I am using 6.8.0 and Qt Creator 15 RC, the latter not being relevant as it is a runtime error, I guess. -
@Mewo said in Type not defined after registering with qmlRegisterSingletonInstance:
In my real-life code I want to instantiate an instance of a class in c++ and hand it over to QML without setting it as a context property, hence the call to qmlRegisterSingletonInstance.
This is often how I want to do things but I feel that Qt somewhat obscures the best practices to achieve it. I have learned recently that even
qmlRegisterSingletonInstance
is not advised these days. This thread might be useful to you: https://forum.qt.io/topic/158630/qml-and-qt-quick -
Instead of using this, can you use QML_ELEMENT & QML_SINGLETON & use singleton.
class MySingleTon : public QObject { Q_OBJECT QML_ELEMENT QML_SINGLETON public: explicit MySingleTon(QObject *parent = nullptr); signals: public slots : void printMe(); }; QML import MySingleTon Window { width: 640 height: 480 visible: true title: qsTr("Hello World") MouseArea{ anchors.fill: parent onClicked: { MySingleTon.printMe(); } } }
In your code it is an issue of name. _ or lower case is an issue. _singletonInstance change to SingletonInstance. E.g
```
MySingleTon *ton = new MySingleTon;
qmlRegisterSingletonInstance("PthinkS.Com",1,0,"MyTon",ton); -
Changing the name fixed the runtime error, thank you. However, qmlls still complains about the import ("Warnings occured while importing...") and says "Unqualified access". Can you tell me why?
In my real-life code I want to instantiate an instance of a class in c++ and hand it over to QML without setting it as a context property, hence the call to qmlRegisterSingletonInstance.
-
@Mewo said in Type not defined after registering with qmlRegisterSingletonInstance:
In my real-life code I want to instantiate an instance of a class in c++ and hand it over to QML without setting it as a context property, hence the call to qmlRegisterSingletonInstance.
This is often how I want to do things but I feel that Qt somewhat obscures the best practices to achieve it. I have learned recently that even
qmlRegisterSingletonInstance
is not advised these days. This thread might be useful to you: https://forum.qt.io/topic/158630/qml-and-qt-quick -
@Mewo Also move the ticket solved
-