qtqmlqtquick2qquickitem

Qt : How to monitor a Q_PROPERTY change on C++ side instead of QML


I am using Qt 5.9.3. I have following property declared in my app's main.qml

Code:

//main.qml
MyQuickItem {

    property color nextColor
    onNextColorChanged: {
        console.log("The next color will be: " + nextColor.toString())
    }
}

// MyQuickItem.h
class MyQuickItem : public QQuickItem {

}

Question:

How can I make onNextColorChanged be defined in the C++ side?

I know that I can also make nextColor as a property inside C++ class MyQuickItem. like so

// MyQuickItem.h
class MyQuickItem : public QQuickItem {

    Q_PROPERTY(QColor nextColor READ nextColor WRITE setNextColor NOTIFY nextColorChanged)
}

Is it possible to monitor OnNextColorChanged inside MyQuickItem?


Solution

  • We can use the QMetaObject to obtain the property and the signal, then we connect it through the old style:

    #ifndef MYQUICKITEM_H
    #define MYQUICKITEM_H
    
    #include <QQuickItem>
    #include <QDebug>
    
    class MyQuickItem : public QQuickItem
    {
        Q_OBJECT
    public:
        MyQuickItem(QQuickItem *parent = Q_NULLPTR): QQuickItem(parent){}
    protected:
        void componentComplete(){
            int index =metaObject()->indexOfProperty("nextColor");
            const QMetaProperty property = metaObject()->property(index);
            if (property.hasNotifySignal()){
                const QMetaMethod s = property.notifySignal();
                QString sig = QString("2%1").arg(QString(s.methodSignature()));
                connect(this, sig.toStdString().c_str() , this, SLOT(onNextColorChanged()));
            }
        }
    private slots:
        void onNextColorChanged(){
            int index =metaObject()->indexOfProperty("nextColor");
            const QMetaProperty property = metaObject()->property(index);
            qDebug()<<"color" << property.read(this);
        }
    };
    
    #endif // MYQUICKITEM_H
    

    The complete example can be found in the following link.