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?
Forum Updated to NodeBB v4.3 + New Features

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

Scheduled Pinned Locked Moved Solved QML and Qt Quick
13 Posts 4 Posters 2.2k Views 1 Watching
  • 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.
  • 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 Online
                    GrecKoG Online
                    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