Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. [solved] setContextProperty not updated dynamically
Forum Updated to NodeBB v4.3 + New Features

[solved] setContextProperty not updated dynamically

Scheduled Pinned Locked Moved QML and Qt Quick
6 Posts 2 Posters 4.1k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R Offline
    R Offline
    Rizzer
    wrote on last edited by
    #1

    Variables in C++ can be accessed in QML by applying QQmlContext::setContextProperty. I understand from the documentation that this was supposed to be dynamic, such that if value of the property is changed, the QML engine is notified so the display can be updated. But I'm finding the relationship is not dynamic. QML keeps the same value that was set at the time setContextProperty was used. Have I misunderstand how setContextProperty operates?

    The problem can be easily demonstrated from a new project in QtCreator (standard QtQuick application), modified:
    @
    #include <QApplication>
    #include <QQmlApplicationEngine>
    #include <QQmlContext>

    int main(int argc, char *argv[])
    {
    QApplication app(argc, argv);

    QQmlApplicationEngine engine;
    
    QQmlContext *ctxt = engine.rootContext();
    
    QString testString("one");
    testString += " two";
    ctxt->setContextProperty("testString", QVariant(testString) );
    testString +=" three";
    
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    
    testString +=" four";
    
    return app.exec&#40;&#41;;
    

    }
    @

    with main.qml
    @
    import QtQuick 2.3
    import QtQuick.Controls 1.2

    ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    menuBar: MenuBar {
        Menu {
            title: qsTr("File")
            MenuItem {
                text: qsTr("&Open")
                onTriggered: console.log("Open action triggered");
            }
            MenuItem {
                text: qsTr("Exit")
                onTriggered: Qt.quit();
            }
        }
    }
    
    Text {
        text: testString
        anchors.centerIn: parent
    }
    

    }
    @

    With this code, the final value of testString is "one two three four". But setContextProperty is invoked at the point where testString="one two", and that is all that gets shown in the QML display. What did I miss?

    1 Reply Last reply
    0
    • p3c0P Offline
      p3c0P Offline
      p3c0
      Moderators
      wrote on last edited by
      #2

      Hi,

      From the Docs:

      bq. For maximum interoperability with QML, any property that is writable should have an associated NOTIFY signal that is emitted whenever the property value has changed.

      In the above case since the property is already changed, the QML is able to get the changes. Further changes (i.e after loading QML) needs to be notified.
      You will need to use Q_PROPERTY for that.
      Check "this":http://qt-project.org/doc/qt-5/qtqml-cppintegration-exposecppattributes.html#exposing-properties example.

      157

      1 Reply Last reply
      0
      • R Offline
        R Offline
        Rizzer
        wrote on last edited by
        #3

        I think I get it: the dynamic updating is not automatic, but needs to be actuated by a NOTIFY mechanism to signal that the value has changed.

        Q_PROPERTY operates on class members (more specifically, QObject members). Am I right to understand that means there is no way to dynamically update general variables (C++ variables which are not members of a QObject subclass) ? I'd have to set up something like a singleton class instead.

        1 Reply Last reply
        0
        • p3c0P Offline
          p3c0P Offline
          p3c0
          Moderators
          wrote on last edited by
          #4

          bq. Am I right to understand that means there is no way to dynamically update general variables (C++ variables which are not members of a QObject subclass) ? I’d have to set up something like a singleton class instead.

          If you know when the variable's value is going to change you can write a Q_INVOKABLE function which will return the new value and call this function from the QML. But can't be termed as dynamic.
          Yes to take the full advantage of Binding and stuff it's better to create a class and set it as contextProperty as shown in the example.

          157

          1 Reply Last reply
          0
          • R Offline
            R Offline
            Rizzer
            wrote on last edited by
            #5

            I've got it working now using a Q_PROPERTY member in a new subclass of QObject.

            When I tried to access the field in QML it gave a thread error "QQmlEngine: Illegal attempt to connect to object that is in a different thread than the QML engine QQmlApplicationEngine". I seem to have fixed that by using the app object as a parent to make sure they're in the same thread.
            @QApplication app(argc, argv);
            MyQObject myqobject(&app);
            ...
            ctxt->setContextProperty("myqobject", &myDebugObject-- );
            @

            Thanks for your help!

            1 Reply Last reply
            0
            • p3c0P Offline
              p3c0P Offline
              p3c0
              Moderators
              wrote on last edited by
              #6

              You're Welcome. Have fun :)

              157

              1 Reply Last reply
              0

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved