Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Solved Create QML component from C++. How?

    QML and Qt Quick
    1
    3
    264
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • B
      bogong 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.

      1 Reply Last reply Reply Quote 0
      • B
        bogong 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?

        1 Reply Last reply Reply Quote 0
        • B
          bogong 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 Reply Last reply Reply Quote 0
          • First post
            Last post