Important: Please read the Qt Code of Conduct -

Auto Binding 2 ways with Cpp Dynamic Property

  • Hi everyone !

    I know how Qt binding work, but it not work for Dynamic Property.
    Then I'm trying to implement 2 ways binding support Dynamic Property use simple function.

    The ideal is use eventFilter on DynamicPropertyChangedEvent to get notify when DynamicProperty changed then update destination property. (This is done as the code below)

    Q_INVOKABLE void binding(QObject* qmlObj, QString qmlProp, QObject* cppObj, QString cppProp);

    My class DynamicObject work as Context Object for an qml component

    class DynamicObject : public QObject
        QMap<QString, QVariant> bindingList;
        QMap<QString, QStringList> cppToQml;
        bool eventFilter(QObject *obj, QEvent *event);
        Q_INVOKABLE void binding(QObject* qmlObj, QString qmlProp, QObject* cppObj, QString cppProp);
        Q_INVOKABLE QObject* thisContextObject();
    void DynamicObject::autoBinding(QObject* qmlObj, QString qmlProp, QObject* cppObj, QString cppProp)
        //Set value from source (cpp) to qml
        qmlObj->setProperty(qPrintable(qmlProp), cppObj->property(qPrintable(cppProp)));
        // ==> Setup auto binding from source (cpp) to destination (qml)
        //Generate Unique Key for this binding
        QString uniqueKey = QString("%1%2%3%4").arg((size_t)qmlObj).arg(qmlProp).arg(size_t(cppObj)).arg(cppProp);
        qDebug() << "Binding Key: " + uniqueKey;
        if (!bindingList.contains(uniqueKey))
            //Add Binding Info into Binding List
            BindingInfo* bInfo = new BindingInfo(qmlObj, qmlProp, cppObj, cppProp);
            QVariant val = QVariant::fromValue(bInfo);
            bindingList.insert(uniqueKey, val);
            //Add Binding Map for Cpp Property to Qml Property
            QStringList qmlPropList;
            if (cppToQml.contains(cppProp))
                qmlPropList = cppToQml.value(cppProp);
            cppToQml[cppProp] = qmlPropList;
        // ==> Setup auto binding from destination (qml) to source (cpp)
        QVariant qmlVal = qmlObj->property(qPrintable(qmlProp));
        qDebug() << qmlVal;
        if (qmlProp == "text") {
            //Try to connect qml signal textChanged with a lot in this object
            QObject::connect(qmlObj, SIGNAL(textChanged()), this, onTextChanged);
            //Try to forward qml object's events use event filter
    bool DynamicObject::eventFilter(QObject *obj, QEvent *event)
        qDebug() << "Event Captured: " << event->type() << " on Object (" << obj << ")";
        if (event->type() == QEvent::KeyPress)
            QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
            qDebug("Key pressed: %d", keyEvent->key());
        if (event->type() == QEvent::KeyRelease)
            QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
            qDebug("Key released: %d", keyEvent->key());
        if (event->type() == QEvent::DynamicPropertyChange) {
            QDynamicPropertyChangeEvent *propEvent = static_cast<QDynamicPropertyChangeEvent *>(event);
            QString propName = propEvent->propertyName();
            qDebug() << (size_t)obj << ":" << propName;

    But it more difficult when I try to get notity when Qml Property changed

    I'm tried eventFilter, but for each controls, I have to handle correct event (To much switch case)

    Then I try to connect <property>Changed SIGNAL with corresponded slot (ex: textChanged => onTextChanged).
    I got the pointer to qml Object & property name which I need to "listen" on, But I don't know how to cast QObject to Qml Type (for example: QObject to TextField)

    Any one have any ideal or solution for this?! Please help !!!

  • I'm really need help !!!

    Any Qt core Development team, Qt Professional or Qt Moderator here can point out a direction for me?
    Or any suggestion please !!!

  • Lifetime Qt Champion


    Why do you need a big switch case ?

    Since these are all dynamic properties, what do you need to cast the QObjects ?

    If you are in such need for help, then you should maybe consider getting a commercial license which include support or hire someone to help you on this.

  • Dear @SGaist

    "Why do you need a big switch case ?"

    • As you can see in the DynamicObject::eventFilter. It already check if DynamicPropertyChanged Event fired or not.
      I can get KeyPress, KeyRelease, but can't get DynamicPropertyChange. So, if I handle KeyRelease for TextField or SelectionChanged for ComboBox... etc... it will be a lot of case to switch (or if ... then)

    "What do you need to cast the QObjects"

    In Qml file, I'm setup autoBinding like this

    Component.onCompleted: {
            viewModel = thisContextObject();
            autoBinding(advSearch, "model", viewModel, "FilterList")
            autoBinding(txtName, "model", viewModel, "CompanyName")

    So I'm try to connect textChange signal of TextField (or other Property of other Qml Object) to related slot (in cpp autoBinding function). That why I need to cast QObject to TextField or something else.

  • Lifetime Qt Champion

    There's something I'm not sure I'm following properly. Can you explain a use case for dynamic properties in QML ?

  • @SGaist
    Sorry for late responded. (I don't know why I can't get notification when mine topic got answer or comment.

    Let take an sample Code for the use case

    QQmlContext* ctx = engine.rootContext();
       id : txtName
    Component.onCompleted: {
       viewModel = thisContextObject();
       autoBinding(txtName, "text", viewModel, "SelectedItem.Name");

    As you can see in the Code above.
    I setup an auto Binding between txtName.text <=> "SelectedItem.Name" ("SelectedItem" & "Name" are Dynamic Property in mainViewModel)
    in Qt way (With normal Property declared by Q_PROPERTY), I have to setup a binding for each way like this

       id : txtName
       text : SelectedItem.Name
    Binding {
       target: SelectedItem
       property: "Name"
       value: txtName.text

    What I want is "How to implement Qml to Cpp binding like what Binding Element does.
    if I can have a look at Binding element source code, may be I can figure it out.

  • Lifetime Qt Champion

    You can look at the code without any problem. Just download the sources, either through the maintenance tool or clone it with git.

Log in to reply