Problem with emitting NOTIFY signals of Q_PROPERTY
-
I am a beginner in Qt Quick. I am using Q_PROPERTY to bind a C++ member variable to a qml property. And I am using a C++ function call from qml. The C++ function emits the Notify signal. But the Qml property is not updating its value. Please help.
My backend C++ header file code is:#ifndef BACKEND_H #define BACKEND_H #include <QObject> class Backend:public QObject { Q_OBJECT Q_PROPERTY(QString test READ test WRITE setTest NOTIFY testChanged) public: Backend(QObject *parent=nullptr); void setTest(QString &temp) { m_test=temp; qWarning("Text Changed"); emit testChanged(); } Q_INVOKABLE void buttonClicked() { m_test="Hello"; emit testChanged(); } signals: void testChanged(); public slots: QString test() { return m_test; } public: QString m_test; }; #endif // BACKEND_H
My backend C++ file is:
#include "backend.h"
Backend::Backend(QObject *parent):QObject(parent)
{
m_test="Hello world";}
My main code is:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <backend.h>
#include <QQmlContext>
#include <QQuickView>
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
qmlRegisterType<BackEnd>("io.qt.examples.backend", 1, 0, "BackEnd");
QQmlApplicationEngine engine;
BackEnd data;
engine.rootContext()->setContextProperty("applicationData",&data);
// engine.setSource(QUrl("qrc:/main.qml"));
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));// QQuickView view;
// BackEnd data;
// view.rootContext()->setContextProperty("applicationData", &data);
// view.setSource(QUrl("qrc:/main.qml"));
return app.exec();
}My QML code is:
//your code here
import QtQuick 2.6 import QtQuick.Controls 2.0 import io.backend 1.0 ApplicationWindow { visible: true width: 640 height: 480 title: qsTr("Hello World") Backend{ id:backend } MouseArea { anchors.fill: parent onClicked: applicationData.buttonClicked() } TextField { id: textField x: 198 y: 87 text:backend.test } }
-
You are modifying text in one object, but reading it from another.
Here you modify applicationData - which is defined in your main.cpp as reference to data variable.
onClicked: applicationData.buttonClicked()
However, then you read the test property value from a different object, backend which is instantiated inside QML.
text:backend.test
These 2 objects are 2 completely separate instances of BackEnd class. They have different values and work independently. You need to decide which one you want to use and stick to that (so, either use only backend in your QML, or only applicationData).
-
Thank you very much for the help. It works now
-
Hi and welcome to devnet,
On a side note, your implementation is suboptimal. You should rather do something like:
void setTest(const QString &temp) { if (m_text == temp) { return; } m_test = temp; qWarning("Text Changed"); emit testChanged(); } Q_INVOKABLE void buttonClicked() { setText("Hello"); }
So you really emit testChanged when something has changed.