Properties set on QML's side are not propagated to C++



  • Hi all,
    I've observed strange behaviour that properties set on QML's site are not being propagated to C++ implementation. For example following code:

    Rectangle {
        id: root
        width: 1000
        height: 1000
    
        Sometype {
           width: root.width //parent.width
           height: root.height //parent.height
    //       width: 1000
    //       height: 1000
        }
    }
    

    If width and height are set in Sometype as described then on C++ side in Sometype's constructor or other functions it's values are equal 0. Only if I'll set those properties directly to 1000 this value will be logged on C++ side.
    From QML side it seems like it works correctly no matter which option is being used.
    Can anybody explain me what am I doing wrong?


  • Moderators

    Hi! In case you already have a minimal working example, could you please post that? Would make my life easier trying to reproduce / explain the observed behavior :-)



  • Hi @Wieland,

    here I've provided some quick example: https://github.com/osmial/qt_qml_shape_example

    Frankly it doesn't work as I've explained - the width and height doesn't seem to be correctly propagated only in Shape's ctor. The problem which I've described in previous post I've observed in my project's code. I'll try to reproduce it based on sources which I've linked here.
    So the question for now is: why in Shape's ctor values of the properties are not being propagated (no matter if are set to constant int value or pointed to parent's property value).



  • @osmial The issue is that setting properties does not occur in the constructor. Initial assignment occurs after construction, and prior to QQmlParserStatus::componentComplete(). Any code that relies on property values being correctly set to anything other than default values should wait for that function to be called.

    #include <QQmlApplicationEngine>
    #include <QDebug>
    #include <QQmlParserStatus>
    #include <QCoreApplication>
    
    class MyItem :
            public QObject
            , public QQmlParserStatus
    {
        Q_OBJECT
        Q_INTERFACES(QQmlParserStatus)
        Q_PROPERTY(bool myProp READ myProp WRITE setMyProp NOTIFY myPropChanged)
    
    public:
        MyItem() {
            qDebug() << "MyItem constructor";
        }
        bool myProp() const
        {
            return false;
        }
    public slots:
        void componentComplete()
        {
            qDebug() << "MyItem componentComplete";
        }
        void classBegin()
        {
            qDebug() << "MyItem classBegin";
        }
    
        void setMyProp(bool myProp)
        {
            qDebug() << "setting myProp";
            if (myProp)
                emit myPropChanged(myProp);
        }
    signals:
        void myPropChanged(bool myProp);
    };
    
    int main(int argc, char *argv[])
    {
        QCoreApplication app(argc, argv);
        qmlRegisterType<MyItem>("myStuff", 1, 0, "MyItem");
    
        QQmlApplicationEngine engine;
        engine.loadData("import myStuff 1.0; MyItem { myProp: true }");
    
        return app.exec();
    }
    
    #include "main.moc"
    

Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.