How to get a valid object instance of a QQuickItem on C++ side
-
Alright. I have searched a lot but haven't got a good solution yet. I am new to
Qt. I have a class which is aQQuickItemlike so,class MyQuickItemClass : public QQuickItem { Q_OBJECT SetInfo(SomeCppClass object) };I do a
qmlRegisterTypein mymain.cppto register it on theqmlside like this,qmlRegisterType< MyQuickItemClass >("MyQuickItemClass", 1, 0, "MyQuickItemClass");
All fine till here. But -> I want to set an object instance & some properties in MyQuickItemClass which some C++ logic in it as well & then pass the
MyQuickItemClassobject toqml. Or, get a valid instance ofMyQuickItemClassfrom Qml. How can I get a vlid instanceMyQuickItemClassobject instance fromQMLon C++ side inmain.cpp?I tried doing the following learning from the link here. But this technique creates two separate objects of
MyQuickItemClass. One fromQML, & one fromc++side. Hence does not work for me.Following is how I am trying to do this after lot of searching.
int main(int argc, char *argv[]) { qmlRegisterType< MyQuickItemClass >("MyQuickItemClass", 1, 0, "MyQuickItemClass"); QQmlApplicationEngine engine; SomeCppClass someCppClassObject; someCppClassObject.updateSomething(); MyQuickItemClass myquickItemObject; myquickItemObject.SetInfo(someCppClassObject); engine.rootContext()->setContextProperty("myquickItemObject", &myquickItemObject); engine.load(QUrl(QStringLiteral("qrc:/qml/main.qml"))); return app.exec(); }But, doing the above gets the constructor of
MyQuickItemClasscalled twice. Once fromcppside when I created an object, and once fromqmlside. Verified this by placing a breakpoint in the constructor ofMyQuickItemClassas well. As a result,someCppClassObjectthat I had set is null insideMyQuickItemClasswhen program runs. Because qml has made the final call toMyQuickItemClassto instantiate, thusly ignoring theMyQuickItemClassobject that I created inmain.cpp.Here is my
qml´ code forMyQuickItemClass`:import QtQuick 2.5 import MyQuickItemClass 1.0 ParentContainerItem { id: parentItem color: "black" MyQuickItemClass { id: myQuickItemID visible: true objectName: "myQuickItem" property bool someProperty1: false property bool someProperty2: true anchors.top: parent.top anchors.horizontalCenter: parent.horizontalCenter } //Other qml components }And this is the C++ class whose object needs to be set into
MyQuickItemClass.SomeCppClass { //Pure C++ class. No Qt }Please note that I need to keep
MyQuickItemClassderived fromQQuickItem. Please suggest... -
@Nelson_Piquet Use
findChildto find that instantiated QML type from C++ usingobjectNameand cast it toQQuickItem -
@Nelson_Piquet Use
findChildto find that instantiated QML type from C++ usingobjectNameand cast it toQQuickItem@p3c0 Thanks for your attention on this. Can you pls show some sample code ?
-
-
@p3c0 I saw the code in the link you provided.
QObject *rect = object->findChild<QObject*>("rect"); if (rect) rect->setProperty("color", "red");Can I pass a pure C++ class object instance into
setProperty? -
@Nelson_Piquet I guess. Maybe you can try
QVariant::fromValuebut first Does this solve your original question? I.e getting access of QML object from C++? -
@Nelson_Piquet I guess. Maybe you can try
QVariant::fromValuebut first Does this solve your original question? I.e getting access of QML object from C++?@p3c0 I read & tried to understand this technique of
findChild. Not sure how I can change mymain.cppto include this technique offindchild. Doesnt it require to change the way I am loading mymain.qml? Below is the full code demonstration of how I should do this withfindchild. Right ?QQuickView view; view.setSource(QUrl::fromLocalFile("main.qml")); view.show(); QObject *object = view.rootObject(); QObject *rect = object->findChild<QObject*>("MyQuickItemClass"); if (rect) rect->setProperty("color", "red");But Can I set a C++ class object into
SetProperty?I looked at some other possibilities: Below is something I have cooked up but YET TO SOLVE THE PROBLEM !!!!
qmlRegisterType< MyQuickItemClass >("MyQuickItemClass", 1, 0, "MyQuickItemClass"); QQmlApplicationEngine engine; HelloCpp cppObjectOnqmlSide; qmlRegisterType<HelloCpp>("HelloCppClass", 1, 0, "HelloCppObj"); engine.rootContext()->setContextProperty("theCppObject", &cppObjectOnqmlSide); engine.load(QUrl(QStringLiteral("qrc:/qml/main.qml"))); return app.exec();Now on the QML side, below is what I am doing
import HelloCppClass 1.0 HelloCppObj { id: theCppObject } MyQuickItemClass { id: myQuickItemID visible: true objectName: "myQuickItem" property bool someProperty1: false property bool someProperty2: true anchors.top: parent.top anchors.horizontalCenter: parent.horizontalCenter Component.onCompleted: { print("MyQuickItemClass Component.onCompleted called") theCppObject.printMessage("someMessage") //Can I pass MyQuickItemClass object into printMessage ? }}
My question is : Can I pass MyQuickItemClass object into printMessage ? How should I change printMessage to do that ? If I can, then this should solve my problem
-
@Nelson_Piquet Your original question as seen in the title of this post:
How to get a valid object instance of a QQuickItem on C++ side
Yes. Using
findChildwas the answer.Now coming to your second question:
Can I pass MyQuickItemClass object into printMessage ? How should I change printMessage to do that ? If I can, then this should solve my problem
Yes. Modify your
printMessagefunction to acceptMyQuickItemClassclass instance as a paramater. Then when you call the function from QML just passthisto it:Component.onCompleted: { print("MyQuickItemClass Component.onCompleted called") theCppObject.printMessage(this) }Or if its from outside just pass
MyQuickItemClassidi.emyQuickItemID -
@Nelson_Piquet Your original question as seen in the title of this post:
How to get a valid object instance of a QQuickItem on C++ side
Yes. Using
findChildwas the answer.Now coming to your second question:
Can I pass MyQuickItemClass object into printMessage ? How should I change printMessage to do that ? If I can, then this should solve my problem
Yes. Modify your
printMessagefunction to acceptMyQuickItemClassclass instance as a paramater. Then when you call the function from QML just passthisto it:Component.onCompleted: { print("MyQuickItemClass Component.onCompleted called") theCppObject.printMessage(this) }Or if its from outside just pass
MyQuickItemClassidi.emyQuickItemID@p3c0 Sorry about swaying from the original question. Thanks a lot for all the information. That helps.