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?

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 31 Aug 2019, 10:06 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 31 Aug 2019, 12:45 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
      • J Offline
        J Offline
        JKSH
        Moderators
        wrote on 31 Aug 2019, 22:11 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 1 Sept 2019, 07:11
        2
        • J JKSH
          31 Aug 2019, 22:11

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

          B Offline
          B Offline
          bogong
          wrote on 1 Sept 2019, 07:11 last edited by bogong 9 Jan 2019, 08:12
          #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

          J 1 Reply Last reply 6 Sept 2019, 22:34
          0
          • B Offline
            B Offline
            bogong
            wrote on 6 Sept 2019, 12:21 last edited by bogong 9 Jun 2019, 12:24
            #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
              1 Sept 2019, 07:11

              @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

              J Offline
              J Offline
              JKSH
              Moderators
              wrote on 6 Sept 2019, 22:34 last edited by JKSH 9 Jun 2019, 22:44
              #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 7 Sept 2019, 07:32
              1
              • J JKSH
                6 Sept 2019, 22:34

                @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 7 Sept 2019, 07:32 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?

                J 1 Reply Last reply 7 Sept 2019, 09:57
                0
                • B bogong
                  7 Sept 2019, 07:32

                  @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?

                  J Offline
                  J Offline
                  JKSH
                  Moderators
                  wrote on 7 Sept 2019, 09:57 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 7 Sept 2019, 11:32
                  1
                  • J JKSH
                    7 Sept 2019, 09:57

                    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 7 Sept 2019, 11:32 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 7 Sept 2019, 14:58 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

                      J 1 Reply Last reply 7 Sept 2019, 22:28
                      1
                      • B bogong
                        7 Sept 2019, 14:58

                        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

                        J Offline
                        J Offline
                        JKSH
                        Moderators
                        wrote on 7 Sept 2019, 22:28 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 9 Sept 2019, 08:57 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 26 Jun 2020, 22:36 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