Q_PROPERTY Produces TypeError When Setting QQuickWidget ContextProperty
-
Hello everyone. I am setting a Q_OBJECT class with a QString Q_PROPERTY in a QQuickWidget. The application loads and displays the test text perfectly fine. However it always produces the error
TypeError: Cannot read property 'message' of nullDebugging shows the type error is produced in the Application Output in MainWindow's constructor where
ui->qmlQuickWidget->rootContext()->setContextProperty("testQML", &testQML);and the QML Debugger Console from w.show() in main.
Is there a way of setting the QML file that will remove this error from occurring or a better implementation in the .qml file itself?
I am running on QT 6.9.3 on Windows 10. All the relevant code is below. Thank you.
//TestQML.qml import QtQuick 2.15 Text{ text: testQML.message }//MainWindow.cpp #include "MainWindow.hpp" #include "TestQML.hpp" #include "./ui_mainwindow.h" #include <QQmlContext> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow){ ui->setupUi(this); TestQML testQML; testQML.setMessage(QString("test")); ui->qmlQuickWidget->rootContext()->setContextProperty("testQML", &testQML); ui->qmlQuickWidget->setSource(QUrl::fromLocalFile("../../TestQML.qml")); } MainWindow::~MainWindow() { delete ui; }//TestQML.cpp #include "TestQML.hpp" TestQML::TestQML(QObject *parent) : QObject(parent){ myMessage = "Test Message"; } QString TestQML::message() const { return myMessage; } void TestQML::setMessage(const QString &newMessage){ if (myMessage != newMessage) { myMessage = newMessage; emit messageChanged(); } }//TestQML.hpp #ifndef TESTQML_HPP #define TESTQML_HPP #include <QObject> #include <QString> class TestQML : public QObject { Q_OBJECT Q_PROPERTY(QString message READ message WRITE setMessage NOTIFY messageChanged) public: explicit TestQML(QObject *parent = nullptr); QString message() const; void setMessage(const QString &newMessage); signals: void messageChanged(); private: QString myMessage; }; #endif // TESTQML_HPP -
Hello everyone. I am setting a Q_OBJECT class with a QString Q_PROPERTY in a QQuickWidget. The application loads and displays the test text perfectly fine. However it always produces the error
TypeError: Cannot read property 'message' of nullDebugging shows the type error is produced in the Application Output in MainWindow's constructor where
ui->qmlQuickWidget->rootContext()->setContextProperty("testQML", &testQML);and the QML Debugger Console from w.show() in main.
Is there a way of setting the QML file that will remove this error from occurring or a better implementation in the .qml file itself?
I am running on QT 6.9.3 on Windows 10. All the relevant code is below. Thank you.
//TestQML.qml import QtQuick 2.15 Text{ text: testQML.message }//MainWindow.cpp #include "MainWindow.hpp" #include "TestQML.hpp" #include "./ui_mainwindow.h" #include <QQmlContext> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow){ ui->setupUi(this); TestQML testQML; testQML.setMessage(QString("test")); ui->qmlQuickWidget->rootContext()->setContextProperty("testQML", &testQML); ui->qmlQuickWidget->setSource(QUrl::fromLocalFile("../../TestQML.qml")); } MainWindow::~MainWindow() { delete ui; }//TestQML.cpp #include "TestQML.hpp" TestQML::TestQML(QObject *parent) : QObject(parent){ myMessage = "Test Message"; } QString TestQML::message() const { return myMessage; } void TestQML::setMessage(const QString &newMessage){ if (myMessage != newMessage) { myMessage = newMessage; emit messageChanged(); } }//TestQML.hpp #ifndef TESTQML_HPP #define TESTQML_HPP #include <QObject> #include <QString> class TestQML : public QObject { Q_OBJECT Q_PROPERTY(QString message READ message WRITE setMessage NOTIFY messageChanged) public: explicit TestQML(QObject *parent = nullptr); QString message() const; void setMessage(const QString &newMessage); signals: void messageChanged(); private: QString myMessage; }; #endif // TESTQML_HPP@daviddev The main issue is that your
TestQMLobject is a local variable -- it gets destroyed as soon as theMainWindowconstructor returns. So, a quick fix is to allocate yourTestQMLobject on the heap (auto testQML = new TestQML(this);).However, that is not the recommended fix. We recommend making your
TestQMLobject a QML singleton, using theQML_ELEMENTandQML_SINGLETONmacros (see https://doc.qt.io/qt-6/qtqml-cppintegration-overview.html ) -
I greatly appreciate this. Would there be a project that has a QML_SINGLETON implementation with a QQuickWidget you know about? The closest source I have discovered is this forum post however it uses a QQMLApplicationEngine connection while I am trying to use QQuickWidget. The closest Example QT provides is the QQuickWidgetVersusWindow_opengl which I am getting lost in.
https://forum.qt.io/topic/133764/unable-to-access-q_property-for-qml_singleton-object?_=1761145429336Also, when should I use the pragma Singleton in the .qml file vs the QML_ELEMENT and QML_SINGLETON?
-
I have resolved the TypeError error with both a Singleton approach as well as the heap approach. I am trying to post the heap solution below, but it keeps getting marked as spam, as well as the Qml implenetation for the Singleton. I have unfortunately had to use a pointer in the MainWindow header file for the QQuickWidget and set it in the Window's constructor.
Would somebody know how to setup the Singleton version that will update the QQuickWidget? I am able to setup the Singleton version, however I have not been able to update it for the life of me.
-
I greatly appreciate this. Would there be a project that has a QML_SINGLETON implementation with a QQuickWidget you know about? The closest source I have discovered is this forum post however it uses a QQMLApplicationEngine connection while I am trying to use QQuickWidget. The closest Example QT provides is the QQuickWidgetVersusWindow_opengl which I am getting lost in.
https://forum.qt.io/topic/133764/unable-to-access-q_property-for-qml_singleton-object?_=1761145429336Also, when should I use the pragma Singleton in the .qml file vs the QML_ELEMENT and QML_SINGLETON?
@daviddev said in Q_PROPERTY Produces TypeError When Setting QQuickWidget ContextProperty:
when should I use the pragma Singleton in the .qml file vs the QML_ELEMENT and QML_SINGLETON?
- Use the pragma if you implement your singleton in QML
- Use QML_ELEMENT if you implement your singleton in C++
Would somebody know how to setup the Singleton version that will update the QQuickWidget? I am able to setup the Singleton version, however I have not been able to update it for the life of me.
The QML engine instantiates the singleton, so you don't do that manually.
You can retrieve a pointer to your singleton by calling
QQmlEngine::singletonInstance<>(): https://doc.qt.io/qt-6/qqmlengine.html#singletonInstance-1// Replace "MyModule" with your actual module's name auto instance = ui->qmlQuickWidget->engine()->singletonInstance<TestQML*>("MyModule", "TestQML"); instance->updateSomething();Note: To avoid confusion, I recommend that you give your C++ class and your *.qml file different names
-
D daviddev has marked this topic as solved