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"); } }
-
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); } } }
-
@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. -
@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 }
-
I got it!
It look like
e.Handled = true/false;
in .Net EventI'll keep it in mind for further Implementation.
Thanks you !