Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Error in creating QML Component from C++. Why?
QtWS25 Last Chance

Error in creating QML Component from C++. Why?

Scheduled Pinned Locked Moved Solved QML and Qt Quick
13 Posts 4 Posters 2.1k Views
  • 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 Offline
    B Offline
    bogong
    wrote on last edited by bogong
    #1

    Hello!
    I am trying to create QML Component from C++. Everything works fine, but I have this errors in log on start application (When I am trying to create it in QML - no errors):

    qrc:/ButtonExit.qml:30: TypeError: Cannot read property 'width' of null
    qrc:/ButtonExit.qml:32: TypeError: Cannot read property 'horizontalCenter' of null
    

    on kill application

    qrc:/ButtonExit.qml:32: TypeError: Cannot read property 'horizontalCenter' of undefined
    qrc:/ButtonExit.qml:38: TypeError: Cannot read property 'horizontalCenter' of undefined
    

    Every property that is predefined in button.qml within "parent" rising error but everything works fine:

    Rectangle {
    
    	id: buttonExit;
    	objectName: "buttonExit";
    	color: COLOR.blueDark();
    	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: COLOR.whiteClean();
    		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");
    
    	if (oBottomBlock) {
    
    		QQmlComponent oComponent(&Engine,QUrl(QString("qrc:/ButtonExit.qml")));
    		QObject *oButtonExit = oComponent.create();
    		oButtonExit->setParent(oBottomBlock);
    		QQuickItem *oItemButtonExit = qobject_cast<QQuickItem*>(oButtonExit);
    		oItemButtonExit->setParentItem(qobject_cast<QQuickItem*>(oBottomBlock));
    
    		aLOG << oBottomBlock;
    		aLOG << oBottomBlock->children();
    	}
    
    	return Application.exec();
    }
    

    How to avoid this errors?

    1 Reply Last reply
    0
    • B Offline
      B Offline
      bogong
      wrote on last edited by
      #2

      I found this thread https://stackoverflow.com/questions/34721748/is-it-possible-to-access-qml-anchors-from-c related to issue.

      1 Reply Last reply
      0
      • JKSHJ Offline
        JKSHJ Offline
        JKSH
        Moderators
        wrote on last edited by
        #3

        @bogong see https://forum.qt.io/topic/53666/adding-qml-element-from-c

        Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

        B 1 Reply Last reply
        2
        • JKSHJ JKSH

          @bogong see https://forum.qt.io/topic/53666/adding-qml-element-from-c

          B Offline
          B Offline
          bogong
          wrote on last edited by bogong
          #4

          @jksh said in Error in creating QML Component from C++. Why?:

          @bogong see https://forum.qt.io/topic/53666/adding-qml-element-from-c

          I've seen it and upvoted it too before :) This the first thread that been reading. The problem that I have slightly different - when I mean "parent", I mean "parent" defined inside of QML, not in C++. This parent inside of QML working (thx to you first thread) but I have error messages in log for every property in QML that is defined through calling parent.

          The question is why I have error messages but it's working how it has to be working? Why there are error messages only when I am trying to define for example "width" not like number but like "parent.width" inside of QML.

          The global idea is to create adoptive ui component from C++ that is using relative value (parented) and anchors instead of numbers and constants.

          This what do I mean in QML created from C++:

          Rectangle {
              ...
              width: parent.width;
              anchors.horizontalCenter: parent.horizontalCenter;
              ...
          }
          

          When I am using this relative definition of "width" for example - it's working perfectly but I have error message. When I am using the same directly in QML - no any error and the same result, it's happening only when I am creating QML component that contain relative values from C++ only.

          Rectangle {
              ...
              width: 300;
              ...
          }
          

          When I am using constant value instead of relative - it's working perfectly too and no any error messages.
          Just tested on Qt 5.12.4 and Qt 5.13

          JKSHJ 1 Reply Last reply
          0
          • B Offline
            B Offline
            bogong
            wrote on last edited by bogong
            #5

            The same issue appeared on Qt 5.13.1. The source of example published here.

            QML debugging is enabled. Only use this in a safe environment.
            qrc:/ButtonExit.qml:30: TypeError: Cannot read property 'width' of null
            qrc:/ButtonExit.qml:32: TypeError: Cannot read property 'horizontalCenter' of null
            qrc:/PaddingItem.qml:27: TypeError: Cannot read property 'width' of null
            1567772412676 QQuickColumn(0x7ffaf842e570, name = "bottomBlock")
            1567772412676 (QQuickRectangle(0x7ffb185b6a70, name = "buttonExit"), QQuickItem(0x7ffaf8469080, name = "paddingButtom"))
            

            Is it bug or not?

            1 Reply Last reply
            0
            • B bogong

              @jksh said in Error in creating QML Component from C++. Why?:

              @bogong see https://forum.qt.io/topic/53666/adding-qml-element-from-c

              I've seen it and upvoted it too before :) This the first thread that been reading. The problem that I have slightly different - when I mean "parent", I mean "parent" defined inside of QML, not in C++. This parent inside of QML working (thx to you first thread) but I have error messages in log for every property in QML that is defined through calling parent.

              The question is why I have error messages but it's working how it has to be working? Why there are error messages only when I am trying to define for example "width" not like number but like "parent.width" inside of QML.

              The global idea is to create adoptive ui component from C++ that is using relative value (parented) and anchors instead of numbers and constants.

              This what do I mean in QML created from C++:

              Rectangle {
                  ...
                  width: parent.width;
                  anchors.horizontalCenter: parent.horizontalCenter;
                  ...
              }
              

              When I am using this relative definition of "width" for example - it's working perfectly but I have error message. When I am using the same directly in QML - no any error and the same result, it's happening only when I am creating QML component that contain relative values from C++ only.

              Rectangle {
                  ...
                  width: 300;
                  ...
              }
              

              When I am using constant value instead of relative - it's working perfectly too and no any error messages.
              Just tested on Qt 5.12.4 and Qt 5.13

              JKSHJ Offline
              JKSHJ Offline
              JKSH
              Moderators
              wrote on last edited by JKSH
              #6

              @bogong said in Error in creating QML Component from C++. Why?:

              The question is why I have error messages but it's working how it has to be working? Why there are error messages only when I am trying to define for example "width" not like number but like "parent.width" inside of QML.

              When you call QQmlComponent oComponentButtonExit(&Engine,QUrl(QString("qrc:/ButtonExit.qml")));, Qt creates your ButtonExit item and binds all the properties. However, it does not have a parent at this point, so the error message is correct: parent is null.

              After the ButtonExit is created, you set the parent so the property bindings start working.

              To see this in action, add some debug messages:

              QQmlComponent oComponentButtonExit(&Engine,QUrl(QString("qrc:/ButtonExit.qml")));
              QObject *oButtonExit = oComponentButtonExit.create();
              QQuickItem *oItemButtonExit = qobject_cast<QQuickItem*>(oButtonExit);
              
              qDebug() << "Before: " << oItemButtonExit; // <-- Add this
              
              oItemButtonExit->setParentItem(qobject_cast<QQuickItem*>(oBottomBlock));
              oButtonExit->setParent(oBottomBlock);
              
              qDebug() << "After: " << oItemButtonExit; // <-- Add this
              

              Notes:

              • Do replace dynamic_cast with qobject_cast which is much more robust.
              • QQuickItem inherits QObject, so oButtonExit is redundant. Just do all your operations on oItemButtonExit:
              QQuickItem *oItemButtonExit = qobject_cast<QQuickItem*>(oComponentButtonExit.create());
              oItemButtonExit->setParentItem(...);
              oItemButtonExit->setParent(...);
              

              Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

              B 1 Reply Last reply
              1
              • JKSHJ JKSH

                @bogong said in Error in creating QML Component from C++. Why?:

                The question is why I have error messages but it's working how it has to be working? Why there are error messages only when I am trying to define for example "width" not like number but like "parent.width" inside of QML.

                When you call QQmlComponent oComponentButtonExit(&Engine,QUrl(QString("qrc:/ButtonExit.qml")));, Qt creates your ButtonExit item and binds all the properties. However, it does not have a parent at this point, so the error message is correct: parent is null.

                After the ButtonExit is created, you set the parent so the property bindings start working.

                To see this in action, add some debug messages:

                QQmlComponent oComponentButtonExit(&Engine,QUrl(QString("qrc:/ButtonExit.qml")));
                QObject *oButtonExit = oComponentButtonExit.create();
                QQuickItem *oItemButtonExit = qobject_cast<QQuickItem*>(oButtonExit);
                
                qDebug() << "Before: " << oItemButtonExit; // <-- Add this
                
                oItemButtonExit->setParentItem(qobject_cast<QQuickItem*>(oBottomBlock));
                oButtonExit->setParent(oBottomBlock);
                
                qDebug() << "After: " << oItemButtonExit; // <-- Add this
                

                Notes:

                • Do replace dynamic_cast with qobject_cast which is much more robust.
                • QQuickItem inherits QObject, so oButtonExit is redundant. Just do all your operations on oItemButtonExit:
                QQuickItem *oItemButtonExit = qobject_cast<QQuickItem*>(oComponentButtonExit.create());
                oItemButtonExit->setParentItem(...);
                oItemButtonExit->setParent(...);
                
                B Offline
                B Offline
                bogong
                wrote on last edited by
                #7

                @jksh SUPER-MEGA-HUGE Thanks to you for this explanation. It's making clear for me now. Is there any way to create with parent for avoiding this messages?

                JKSHJ 1 Reply Last reply
                0
                • B bogong

                  @jksh SUPER-MEGA-HUGE Thanks to you for this explanation. It's making clear for me now. Is there any way to create with parent for avoiding this messages?

                  JKSHJ Offline
                  JKSHJ Offline
                  JKSH
                  Moderators
                  wrote on last edited by
                  #8

                  You're welcome!

                  @bogong said in Error in creating QML Component from C++. Why?:

                  Is there any way to create with parent for avoiding this messages?

                  I haven't tried it myself, but I think you must avoid QQmlComponent::create().

                  1. Call QQmlComponent::beginCreate()
                  2. Set the parent
                  3. Call QQmlComponent::completeCreate()

                  See https://doc.qt.io/qt-5/qqmlcomponent.html#beginCreate

                  Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                  B 1 Reply Last reply
                  1
                  • JKSHJ JKSH

                    You're welcome!

                    @bogong said in Error in creating QML Component from C++. Why?:

                    Is there any way to create with parent for avoiding this messages?

                    I haven't tried it myself, but I think you must avoid QQmlComponent::create().

                    1. Call QQmlComponent::beginCreate()
                    2. Set the parent
                    3. Call QQmlComponent::completeCreate()

                    See https://doc.qt.io/qt-5/qqmlcomponent.html#beginCreate

                    B Offline
                    B Offline
                    bogong
                    wrote on last edited by
                    #9

                    @jksh This works fine on creating:

                    QQmlComponent oComponentButtonExit(&Engine,QUrl(QString("qrc:/ButtonExit.qml")));
                    QQuickItem *oItemButtonExit = dynamic_cast<QQuickItem*>(oComponentButtonExit.beginCreate(Engine.rootContext()));
                    oItemButtonExit->setParentItem(dynamic_cast<QQuickItem*>(oBottomBlock));
                    oItemButtonExit->setParent(oBottomBlock);
                    oComponentButtonExit.completeCreate();
                    

                    But there are on killing application still troubles:

                    QML debugging is enabled. Only use this in a safe environment.
                    1567855709534 QQuickColumn(0x7f9c09406a40, name = "bottomBlock")
                    1567855709535 (QQuickRectangle(0x7f9c2b089530, name = "buttonExit"))
                    qrc:/ButtonExit.qml:32: TypeError: Cannot read property 'horizontalCenter' of undefined
                    qrc:/ButtonExit.qml:38: TypeError: Cannot read property 'horizontalCenter' of undefined
                    qrc:/ButtonExit.qml:39: TypeError: Cannot read property 'verticalCenter' of undefined
                    
                    1 Reply Last reply
                    0
                    • B Offline
                      B Offline
                      bogong
                      wrote on last edited by
                      #10

                      Solution found. It's a little tricky but do not rising any error message.
                      Briefly - you have to define object creating function in QML and invoke it from C++. Only then it's working correctly, without any error messages. The example published here

                      JKSHJ 1 Reply Last reply
                      1
                      • B bogong

                        Solution found. It's a little tricky but do not rising any error message.
                        Briefly - you have to define object creating function in QML and invoke it from C++. Only then it's working correctly, without any error messages. The example published here

                        JKSHJ Offline
                        JKSHJ Offline
                        JKSH
                        Moderators
                        wrote on last edited by
                        #11

                        @bogong said in Error in creating QML Component from C++. Why?:

                        Solution found. It's a little tricky but do not rising any error message.
                        Briefly - you have to define object creating function in QML and invoke it from C++. Only then it's working correctly, without any error messages. The example published here

                        I'm glad you found a solution. Happy coding!

                        May I ask why you're using dynamic_cast instead of qobject_cast?

                        Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                        1 Reply Last reply
                        0
                        • GrecKoG Offline
                          GrecKoG Offline
                          GrecKo
                          Qt Champions 2018
                          wrote on last edited by
                          #12

                          For others reading this post :
                          This is not idiomatic QML and generally leads to messy and not really maintenable code

                          https://forum.qt.io/post/548974

                          Don't access QML objects from C++. Instead expose your data from C++ to QML and present or react on it accordingly in QML.

                          1 Reply Last reply
                          1
                          • D Offline
                            D Offline
                            Dylan Bowie
                            wrote on last edited by
                            #13

                            @bogong said in Error in creating QML Component from C++. Why?:

                            nchors.horizontalCenter: parent.horizontalCenter;

                            I'm glad you gays found a solution. Happy coding!

                            But there are other way that work very well and without any error messages too.:

                            Rectangle {
                                   id: buttonExit;
                                   anchors.horizontalCenter: parent ? parent.horizontalCenter : undefined
                            }
                            
                            1 Reply Last reply
                            1

                            • Login

                            • Login or register to search.
                            • First post
                              Last post
                            0
                            • Categories
                            • Recent
                            • Tags
                            • Popular
                            • Users
                            • Groups
                            • Search
                            • Get Qt Extensions
                            • Unsolved