Pass and modify C++ data from a Custom QML Item
-
I would like to pass "simply" a variable (defined in a C++ class, shared to QML with "rootContext()->setContextProperty()" ) to a QML Button and modify it on the OnClick event.
The OnClick event of the CustomBtn would increment the c++ variable with 1.// -------------- main.qml --------------
import QtQuick 2.2 import QtQuick.Controls 1.1 ApplicationWindow { visible: true width: 640 height: 480 title: qsTr("Hello World") CustomBtn { id: aCustomBtn myQMLVar: MyQMLObject.value; } Button { width: 100 height: 62 text: "+2" onClicked: { MyQMLObject.value = MyQMLObject.value+2 } anchors.left: aCustomBtn.right anchors.top: aCustomBtn.top } }// -------------- CustomBtn.qml --------------
import QtQuick 2.0 import QtQuick.Controls 1.1 Item { width: 100 height: 62 property var myQMLVar Button { anchors.fill: parent text: "+1" onClicked: { myQMLVar = myQMLVar+1 } } }// -------------- main.cpp --------------
#include <QApplication> #include <QQmlApplicationEngine> #include <QQmlContext> #include "myobject.h" int main(int argc, char *argv[]) { QApplication app(argc, argv); MyObject anObj; QQmlApplicationEngine engine; engine.rootContext()->setContextProperty("MyQMLObject", &anObj); engine.load(QUrl(QStringLiteral("qrc:///main.qml"))); return app.exec(); }// -------------- myobject.h --------------
#ifndef MYOBJECT_H #define MYOBJECT_H #include <QDebug> #include <QObject> #include <QVariant> class MyObject : public QObject { Q_OBJECT Q_PROPERTY(QVariant value READ value WRITE setValue NOTIFY valueChanged) public: explicit MyObject(QObject *parent = 0); QVariant value() const { return m_value; } signals: void valueChanged(QVariant arg); public slots: void setValue(QVariant arg) { if (m_value != arg) { m_value = arg; qDebug() << "m_value:" << m_value; emit valueChanged(arg); } } private: QVariant m_value; }; #endif // MYOBJECT_HCreate a QtQuick project and include the code above, the "+1" CustomBtn does not increment the C++ variable, when the "+2" normal button increments it.
Did the "myQMLVar" property is correctly defined in the CustomBtn?Is it just impossible to do it this way ?
Will I have to copy paste the code from the CustomBtn calling directly "MyObject.value" for each different C++ variable that I want to modify this way ?
-
I would like to pass "simply" a variable (defined in a C++ class, shared to QML with "rootContext()->setContextProperty()" ) to a QML Button and modify it on the OnClick event.
The OnClick event of the CustomBtn would increment the c++ variable with 1.// -------------- main.qml --------------
import QtQuick 2.2 import QtQuick.Controls 1.1 ApplicationWindow { visible: true width: 640 height: 480 title: qsTr("Hello World") CustomBtn { id: aCustomBtn myQMLVar: MyQMLObject.value; } Button { width: 100 height: 62 text: "+2" onClicked: { MyQMLObject.value = MyQMLObject.value+2 } anchors.left: aCustomBtn.right anchors.top: aCustomBtn.top } }// -------------- CustomBtn.qml --------------
import QtQuick 2.0 import QtQuick.Controls 1.1 Item { width: 100 height: 62 property var myQMLVar Button { anchors.fill: parent text: "+1" onClicked: { myQMLVar = myQMLVar+1 } } }// -------------- main.cpp --------------
#include <QApplication> #include <QQmlApplicationEngine> #include <QQmlContext> #include "myobject.h" int main(int argc, char *argv[]) { QApplication app(argc, argv); MyObject anObj; QQmlApplicationEngine engine; engine.rootContext()->setContextProperty("MyQMLObject", &anObj); engine.load(QUrl(QStringLiteral("qrc:///main.qml"))); return app.exec(); }// -------------- myobject.h --------------
#ifndef MYOBJECT_H #define MYOBJECT_H #include <QDebug> #include <QObject> #include <QVariant> class MyObject : public QObject { Q_OBJECT Q_PROPERTY(QVariant value READ value WRITE setValue NOTIFY valueChanged) public: explicit MyObject(QObject *parent = 0); QVariant value() const { return m_value; } signals: void valueChanged(QVariant arg); public slots: void setValue(QVariant arg) { if (m_value != arg) { m_value = arg; qDebug() << "m_value:" << m_value; emit valueChanged(arg); } } private: QVariant m_value; }; #endif // MYOBJECT_HCreate a QtQuick project and include the code above, the "+1" CustomBtn does not increment the C++ variable, when the "+2" normal button increments it.
Did the "myQMLVar" property is correctly defined in the CustomBtn?Is it just impossible to do it this way ?
Will I have to copy paste the code from the CustomBtn calling directly "MyObject.value" for each different C++ variable that I want to modify this way ?
Hi @Fred-Waltzer,
Binding doesn't work in reverse order i.e updatingmyQMLVarwont re-evaluate the expression and thus it won't updateMyQMLObject.
One way would be to updateMyQMLObjectinmyQMLVarhandler viz.onMyQMLVarChangedbut you may get binding loop.
BTW, Since you have setMyQMLObjectas context property it will be directly accessible inCustomBtntoo. -
Thanks for the answer, that was my biggest fear.
That is exactly what I didn't want to do...
Copy+Paste QML code for each CustomBtn and which will modify a different C++ variable.Didn't they think about factorizing code when they wrote the QML and C++ bindings ?
If anyone found a solution other than COPY-PASTE, I'll be glad to hear about it. -
Thanks for the answer, that was my biggest fear.
That is exactly what I didn't want to do...
Copy+Paste QML code for each CustomBtn and which will modify a different C++ variable.Didn't they think about factorizing code when they wrote the QML and C++ bindings ?
If anyone found a solution other than COPY-PASTE, I'll be glad to hear about it.@Fred-Waltzer
MyQMLObjectwill be available in all the QML files of the project. So no need to create different C++ variable.