How to Notify when Dynamic Property changed



  • I god a TableView with a model "binding" with QList<QObject*> as sample code below:

    My question is : How can I notify when Dynamic Property "Name" is changed?

    If property is pre defined by Q_PROPERTY macro then I can use emit the NOTIFY signal
    Is the any way to implement same NOTIFY signal for Dynamic Property?

    (a Complete sample code would be great - I'm noob) :)

    DynamicObject.h

    class DynamicObject : public QObject
    {
        Q_OBJECT
    public:
        DynamicObject(QObject *parent = 0);
    
        Q_INVOKABLE QVariant binding(const QString &propName) const;
    }
    

    DynamicObject.cpp

    DynamicObject::DynamicObject(QObject *parent)
    {
    
    }
    
    QVariant DynamicObject::binding(const QString &propName) const
    {
        QVariant result = this->property(propName.toStdString().c_str());
        return result;
    }
    

    main.cpp

    int main(int argc, char *argv[])
    {
        QApplication app(argc, argv);
        QQmlApplicationEngine engine;
    
        DatacontextController datacontextController ;
        DynamicObject* dynamicObject = datacontextController.ReadMetadataToDynamicObject(formMetadata);
    
        QQmlContext* ctx = engine.rootContext();
        ctx->setContextObject(dynamicObject);
    
        engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
        return app.exec();
    

    main.qml

    ApplicationWindow {
        id:root
        visible: true
        width: 1024
        height: 768
        title: qsTr("Test Application")
    
        TableView {
    
                id: tblTableView
                anchors.fill: parent
                //parent: rowLayout1
                Layout.fillWidth: true
                Layout.fillHeight: true
    
                TableViewColumn {
                    id:colName
                    title: "Name"
                    width: 150
                    delegate: Text{
                                        text: model.modelData.binding("Name")
                                    }
                model: bindingQList("tableviewItemSource");
        }
    }
    

  • Moderators

    the object on which the property gets changed will receive a QDynamicPropertyChangeEvent event. The event then has a method to get the property name which has changed
    This event can either be handled by reimplementing event() or by installing a event-filter.



  • @raven-worx Thanks for your advise ! I'll try it.



  • I'm implement like this and it work !

    In DynamicObject.h add a signal

    signals:
        void propertyChanged(QVariant propName);
    

    In DynamicObject.cpp reimplement event() handle

    bool DynamicObject::event(QEvent *event)
    {
        //if (event->type() == QDynamicPropertyChangeEvent)
        {
            QDynamicPropertyChangeEvent *const propEvent = static_cast<QDynamicPropertyChangeEvent*>(event);
            QString propName = propEvent->propertyName();
            emit propertyChanged(propName);
            return true;
        }
    
        return false;
    }
    

    And in Qml connect propertyChanged signal like this

    Connections {
                                    target : model.modelData
                                    onPropertyChanged : {
                                        if (propName == "Name")
                                        {
                                            //...Do something with your model.modelData.property(propName);
                                        }
                                    }
                                }
    

  • Moderators

    @Dong said:

    bool DynamicObject::event(QEvent *event)
    {
        //if (event->type() == QDynamicPropertyChangeEvent)
        {
            QDynamicPropertyChangeEvent *const propEvent = static_cast<QDynamicPropertyChangeEvent*>(event);
            QString propName = propEvent->propertyName();
            emit propertyChanged(propName);
            return true;
        }
    
        return false;
    }
    

    just a hint: if you've really implemented the event handler like in this snippet the object wont work like expected. Instead of return false you should return the base class implementation.
    Probably also the "return true" is superfluous for this event type.



  • @raven-worx : Thanks for your notice !

    For now, I just need to emit the PropertyChanged Signal and do nothing with this event.
    I'll take a look at that later.


  • Moderators

    @Dong said:

    For now, I just need to emit the PropertyChanged Signal and do nothing with this event.

    yes, YOU do not need any other events. But the object might. But you are not forwarding any events at all.

    Implement it like this:

    bool DynamicObject::event(QEvent *event)
    {
        if (event->type() == QDynamicPropertyChangeEvent)
        {
            QDynamicPropertyChangeEvent *const propEvent = static_cast<QDynamicPropertyChangeEvent*>(event);
            QString propName = propEvent->propertyName();
            emit propertyChanged(propName);
        }
    
        return QObject::event(event);  //change this to whatever class you are deriving from
    }
    


  • @raven-worx

    I got it!
    It look like
    e.Handled = true/false;
    in .Net Event

    I'll keep it in mind for further Implementation.
    Thanks you !


Log in to reply
 

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