Unsolved 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 aQQuickItem
like so,class MyQuickItemClass : public QQuickItem { Q_OBJECT SetInfo(SomeCppClass object) };
I do a
qmlRegisterType
in mymain.cpp
to register it on theqml
side 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
MyQuickItemClass
object toqml
. Or, get a valid instance ofMyQuickItemClass
from Qml. How can I get a vlid instanceMyQuickItemClass
object instance fromQML
on 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
MyQuickItemClass
called twice. Once fromcpp
side when I created an object, and once fromqml
side. Verified this by placing a breakpoint in the constructor ofMyQuickItemClass
as well. As a result,someCppClassObject
that I had set is null insideMyQuickItemClass
when program runs. Because qml has made the final call toMyQuickItemClass
to instantiate, thusly ignoring theMyQuickItemClass
object that I created inmain.cpp
.Here is my
qml´ code for
MyQuickItemClass`: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
MyQuickItemClass
derived fromQQuickItem
. Please suggest... -
@Nelson_Piquet Use
findChild
to find that instantiated QML type from C++ usingobjectName
and 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::fromValue
but 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.cpp
to 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
findChild
was 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
printMessage
function to acceptMyQuickItemClass
class instance as a paramater. Then when you call the function from QML just passthis
to it:Component.onCompleted: { print("MyQuickItemClass Component.onCompleted called") theCppObject.printMessage(this) }
Or if its from outside just pass
MyQuickItemClass
id
i.emyQuickItemID
-
@p3c0 Sorry about swaying from the original question. Thanks a lot for all the information. That helps.