Mixed QML/C++ app (solved)
-
Hi,
I have created a mixed QML/C++ app, and I would like to be able to create a QML type object and add it to my main.qml as a child, from my main.cpp.I have created it by using :
QQmlComponent component(&engine, "C:/....", QQmlComponent:PreferSynchronous);
QObject *object = component.create();
But now I would like to be able to specify that its parent should be my main.qml.Any idea ?
Thanks !
-
Hi,
I have created a mixed QML/C++ app, and I would like to be able to create a QML type object and add it to my main.qml as a child, from my main.cpp.I have created it by using :
QQmlComponent component(&engine, "C:/....", QQmlComponent:PreferSynchronous);
QObject *object = component.create();
But now I would like to be able to specify that its parent should be my main.qml.Any idea ?
Thanks !
I forgot to say that I also wrote :
QQmlEngine::setObjectOwnerShip(object, QQmlEngine::CppOwnerShip);
object -> setParent(&engine); -
I forgot to say that I also wrote :
QQmlEngine::setObjectOwnerShip(object, QQmlEngine::CppOwnerShip);
object -> setParent(&engine);Hi @LaurianeLt,
I forgot to say that I also wrote :
QQmlEngine::setObjectOwnerShip(object, QQmlEngine::CppOwnerShip);
object -> setParent(&engine);That code sets the object parent, but you need to set the visual parent. See the differences here: http://doc.qt.io/qt-5/qtquick-visualcanvas-visualparent.html
To set the visual parent, use QQuickItem::setParentItem(). (you need to typecast object to QQuickItem first)
-
Hi @LaurianeLt,
I forgot to say that I also wrote :
QQmlEngine::setObjectOwnerShip(object, QQmlEngine::CppOwnerShip);
object -> setParent(&engine);That code sets the object parent, but you need to set the visual parent. See the differences here: http://doc.qt.io/qt-5/qtquick-visualcanvas-visualparent.html
To set the visual parent, use QQuickItem::setParentItem(). (you need to typecast object to QQuickItem first)
Hi @JKSH ,
Thank you for your answer, I will try that and let you know how it worked ! -
I did as you said but I still have some problems, here is what I wrote :
QQmlApplicationEngine engine;
...
QQmlComponent component (&engine, "C:/Qt/.../Rectangle.qml", QQmlComponent:PreferSynchronous);
QQuickItem * object = qobject_cast<QQuickItem*>(component.create());QQmlComponent component1 (&engine, "C:/Qt/.../main.qml", QQmlComponent:PreferSynchronous);
QQuickItem * parent = qobject_cast<QQuickItem*>(component1.create());object->setParent(&engine);
object->setParentItem(parent);
engine.load(QUrl(QStringLiteral("qrc:/main.qml)));First I know that the way I create the "parent", when I run it, it opens two windows, the "main.qml" is launched twice. I would like to be able to define my "engine" as the parent but it's not a QQuickItem..
And even like this, my qml object "rectangle.qml" does not appear in the window when I run it.
-
So I tried to define the visual parent this way :
QQuickItem root = qobject_cast<QQuickItem>(engine.rootObjects().first());
object->setParentItem(root);It's running fine but once again, the rectangle.qml is not displayed...
Any idea ?
-
So I tried to define the visual parent this way :
QQuickItem root = qobject_cast<QQuickItem>(engine.rootObjects().first());
object->setParentItem(root);It's running fine but once again, the rectangle.qml is not displayed...
Any idea ?
Hi,
Please add three backticks (```) before and after your code to make it render nicely.
@LaurianeLt said:
it opens two windows, the "main.qml" is launched twice.
That's because you created the "main.qml" component twice:
QQmlComponent component (&engine, "C:/Qt/.../Rectangle.qml", QQmlComponent:PreferSynchronous); QQuickItem * object = qobject_cast<QQuickItem*>(component.create()); // <-- First creation ... engine.load(QUrl(QStringLiteral("qrc:/main.qml))); // <-- Second creation
I would like to be able to define my "engine" as the parent but it's not a QQuickItem.
Why do you want to set "engine" as the parent?
An item is painted "inside" its visual parent. An engine cannot be painted seen, so it cannot be a visual parent.
And even like this, my qml object "rectangle.qml" does not appear in the window when I run it.
I just realized that you are using QQmlEngine, which means that the root type inside main.qml is probably a
Window
, is that correct? If so, note thatWindow
does not inheritItem
, so it is not a QQuickItem either. Look for the QQuickItems inside theWindow
by callingengine.rootObjects().first()->children()
.I suggest you check the application output on the console. They provide many hints to help you solve your problems. You can print your own messages using qDebug():
qDebug() << engine.rootObjects();
-
Hi,
Please add three backticks (```) before and after your code to make it render nicely.
@LaurianeLt said:
it opens two windows, the "main.qml" is launched twice.
That's because you created the "main.qml" component twice:
QQmlComponent component (&engine, "C:/Qt/.../Rectangle.qml", QQmlComponent:PreferSynchronous); QQuickItem * object = qobject_cast<QQuickItem*>(component.create()); // <-- First creation ... engine.load(QUrl(QStringLiteral("qrc:/main.qml))); // <-- Second creation
I would like to be able to define my "engine" as the parent but it's not a QQuickItem.
Why do you want to set "engine" as the parent?
An item is painted "inside" its visual parent. An engine cannot be painted seen, so it cannot be a visual parent.
And even like this, my qml object "rectangle.qml" does not appear in the window when I run it.
I just realized that you are using QQmlEngine, which means that the root type inside main.qml is probably a
Window
, is that correct? If so, note thatWindow
does not inheritItem
, so it is not a QQuickItem either. Look for the QQuickItems inside theWindow
by callingengine.rootObjects().first()->children()
.I suggest you check the application output on the console. They provide many hints to help you solve your problems. You can print your own messages using qDebug():
qDebug() << engine.rootObjects();
Hi @JKSH,
Thank you so much for your answer and the tip.
I realised I was creating it twice but I wanted to see if I was able this way to make my "main.qml" be the parent of "rectangle.qml".
I realize that what I said was not clear at all. I don't want to set "engine" as the parent, but my "main.qml" which is the qml file I load with the engine.
I am using QQmlEngine indeed so my main.cpp in its simplest form is this :
int main( int argc, char *argv[]) { QApplication app(argc, argv); QQmlApplicationEngine engine; engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); return app.exec(); }
So what I want to be able to do is to create and declare an object "rectangle.qml" a child of "main.qml" from my "main.cpp".
I hope I am making more sense now, I will try to figure more out by looking at the children of engine.rootObjects().first().
Thanks again!
-
@JKSH I forgot : the root type inside main.qml is an
ApplicationWindow
. -
I tried this :
qDebug << engine.rootObjects().first()->children();
And I get something like this, with the list of the children :
(QQuickLoader(0x26c5ff98, QQuickItem(0x26c5fcf8), ... )So I tried to get the second one, which is a QQuickItem like that :
QQuickItem parent = qobject_cast<QQuickItem*>(engine.rootObjects().first()->children().at(2));
But I get a error message saying that
"QQuickItem::QQuickItem(const QQuickItem&)' is private"
. -
I tried this :
qDebug << engine.rootObjects().first()->children();
And I get something like this, with the list of the children :
(QQuickLoader(0x26c5ff98, QQuickItem(0x26c5fcf8), ... )So I tried to get the second one, which is a QQuickItem like that :
QQuickItem parent = qobject_cast<QQuickItem*>(engine.rootObjects().first()->children().at(2));
But I get a error message saying that
"QQuickItem::QQuickItem(const QQuickItem&)' is private"
.@LaurianeLt said:
@JKSH I forgot : the root type inside main.qml is an
ApplicationWindow
.Yep, that inherits
Window
. It's not a QQuickItem.QQuickItem parent = qobject_cast<QQuickItem*>(engine.rootObjects().first()->children().at(2));
But I get a error message saying that
"QQuickItem::QQuickItem(const QQuickItem&)' is private"
.You got that error message because the type of parent needs to be
QQuickItem*
, notQQuickItem
.Also note that counting starts from 0, so if you want the second item you should call
.at(1)
. -
@LaurianeLt said:
@JKSH I forgot : the root type inside main.qml is an
ApplicationWindow
.Yep, that inherits
Window
. It's not a QQuickItem.QQuickItem parent = qobject_cast<QQuickItem*>(engine.rootObjects().first()->children().at(2));
But I get a error message saying that
"QQuickItem::QQuickItem(const QQuickItem&)' is private"
.You got that error message because the type of parent needs to be
QQuickItem*
, notQQuickItem
.Also note that counting starts from 0, so if you want the second item you should call
.at(1)
.@JKSH Thank you so much, this is finally working !
-
@JKSH Thank you so much, this is finally working !
@LaurianeLt You're welcome :) Happy coding!