Create QML component from C++. How?
-
wrote on 31 Aug 2019, 08:08 last edited by bogong
Hello all!
What am I missing? I am trying to create QML dynamically from C++ in following official documentation but got error and QML component do not showing.
main.qml
// Application window Window { property bool isDesktop: GLOBAL.isDesktop(); property real scaleRate: width/GLOBAL.uiWidth(); id: applicationWindow; visible: true; width: isDesktop ? GLOBAL.desktopApplicationWidth() : maximumWidth; height: isDesktop ? GLOBAL.desktopApplicationHeight() : maximumHeight; title: qsTr("QtQuick Hello World"); Rectangle { id: contentWrapper; width: parent.width; height: parent.height; color: COLOR.white(); Column { id: bottomBlock; objectName: "bottomBlock"; width: parent.width; anchors.bottom: parent.bottom; spacing: 10; // ButtonExit {} Item { id: paddingButtom; width: parent.width; height: 30; } } } }
button.qml
Rectangle { id: buttonExit; color: "#000000"; width: parent.width * 0.8; height: width * 0.2; anchors.horizontalCenter: parent.horizontalCenter; Text { id: buttonExitLabel; text: qsTr("Exit"); anchors.horizontalCenter: parent.horizontalCenter; anchors.verticalCenter: parent.verticalCenter; color: "#FFFFFF"; font.pointSize: 18; } MouseArea { id: buttonExitArea; anchors.fill: parent; onClicked: { Qt.quit(); } } }
main.cpp
int main(int Counter, char *Arguments[]) { QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication Application(Counter, Arguments); QQmlApplicationEngine Engine; Engine.load(QUrl(Main)); if (Engine.rootObjects().isEmpty()) { return -1; } QObject *oRootObject = dynamic_cast<QObject*>(Engine.rootObjects()[0]); QObject *oBottomBlock = oRootObject->findChild<QObject*>("bottomBlock"); QQmlComponent oComponent(&Engine,QUrl(QString("qrc:/ButtonExit.qml")),QQmlComponent::PreferSynchronous); QObject *oButtonExit = oComponent.create(); oButtonExit->setParent(oBottomBlock); return Application.exec(); }
When I start it got this error's:
qrc:/ButtonExit.qml:29: TypeError: Cannot read property 'width' of null qrc:/ButtonExit.qml:31: TypeError: Cannot read property 'horizontalCenter' of null qrc:/ButtonExit.qml:37: TypeError: Cannot read property 'horizontalCenter' of undefined qrc:/ButtonExit.qml:38: TypeError: Cannot read property 'verticalCenter' of undefined
It's looks like the Button object do attached to the object but do not see the parent-property in QML. Every property defined through "parent" not working. When I am attaching it directly in QML - everything works fine.
-
wrote on 31 Aug 2019, 08:36 last edited by bogong
When I am dumping children, the button block attached.
main.cpp
int main(int Counter, char *Arguments[]) { QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication Application(Counter, Arguments); QQmlApplicationEngine Engine; Engine.load(QUrl(Main)); if (Engine.rootObjects().isEmpty()) { return -1; } QObject *oRootObject = dynamic_cast<QObject*>(Engine.rootObjects()[0]); QObject *oBottomBlock = oRootObject->findChild<QObject*>("bottomBlock"); if (oBottomBlock) { QQmlComponent oComponent(&Engine,QUrl(QString("qrc:/ButtonExit.qml"))); QObject *oButtonExit = oComponent.create(); oButtonExit->setParent(oBottomBlock); aLOG << oBottomBlock; aLOG << oBottomBlock->children(); } return Application.exec(); }
the log from application:
qrc:/ButtonExit.qml:30: TypeError: Cannot read property 'width' of null qrc:/ButtonExit.qml:32: TypeError: Cannot read property 'horizontalCenter' of null 1567240723538 QQuickColumn(0x7f989ec986e0, name = "bottomBlock") 1567240723538 (QQuickItem(0x7f989ec989e0, name = "paddingButtom"), QQuickRectangle(0x7f989ecaa530, name = "buttonExit"))
And I've got another question - How to put created object in defined place? For example if I want to place "buttonExit" before "paddingButtom". For now it's after. I understand that children - it's only QObjectList, but how to make specially defined order of this QObjectList. Is there any way to put child in special place?
-
wrote on 31 Aug 2019, 09:40 last edited by bogong
Solution found. There are need to be added not like QObject parent, there need to be done like QQuickItem parent. This solution woks for me now:
int main(int Counter, char *Arguments[]) { QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication Application(Counter, Arguments); QQmlApplicationEngine Engine; Engine.load(QUrl(Main)); if (Engine.rootObjects().isEmpty()) { return -1; } QObject *oRootObject = dynamic_cast<QObject*>(Engine.rootObjects()[0]); QObject *oBottomBlock = oRootObject->findChild<QObject*>("bottomBlock"); if (oBottomBlock) { QQmlComponent oComponent(&Engine,QUrl(QString("qrc:/ButtonExit.qml"))); QObject *oButtonExit = oComponent.create(); QQuickItem *oItemButtonExit = qobject_cast<QQuickItem*>(oButtonExit); oItemButtonExit->setParentItem(qobject_cast<QQuickItem*>(oBottomBlock)); } return Application.exec(); }
1/3