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. Change QML-property in C++
QtWS25 Last Chance

Change QML-property in C++

Scheduled Pinned Locked Moved QML and Qt Quick
9 Posts 5 Posters 11.8k Views
  • 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.
  • H Offline
    H Offline
    Hedge
    wrote on last edited by
    #1

    I've got a ToolButton (QML Desktop Widgets) and want to change its icon.

    @ ToolButton{
    objectName: "imgConnected"
    iconSource: "images/not-connected.png"
    anchors.verticalCenter: parent.verticalCenter
    }@

    Now when I try to change the iconSource I do this:

    @
    QDeclarativeView view(QUrl("qml/MyProject/main.qml"));
    view.show();

    // get root object
    QObject *rootObject = dynamic_cast<QObject *>(view.rootObject());
    // find element by name
    QObject *image = rootObject->findChild<QObject *>(QString("imgConnected"));
    
    image->setProperty("iconSource", QString("D:/Dropbox/Projekte/MyProject/release/images/connected.png"));
    

    @

    (I know that I have to remove the absolute path, its just there for testing).

    My problem is that whenever this code is executed another window looking like the Mainwindow pops up for a second and then hides. The iconSource never changes visibly though.

    1 Reply Last reply
    0
    • M Offline
      M Offline
      mburakalkan
      wrote on last edited by
      #2

      What you can do is assign a variable for that icon and change that variable from C++ side so
      that icon updates.. I was using that technique for states and it was working well..

      1 Reply Last reply
      0
      • H Offline
        H Offline
        Hedge
        wrote on last edited by
        #3

        Can you provide an example?

        1 Reply Last reply
        0
        • M Offline
          M Offline
          mburakalkan
          wrote on last edited by
          #4

          Say you have a onStateChange slot somewhere in you QDV implementation and you want to change state property of you QML ui. You could write the slot like that

          @
          void SignageView::onStateChange(const QString &newState)
          {
          QDeclarativeProperty state(rootObject(), QString("state"));

          if (state.type() == QDeclarativeProperty::Invalid) {
              WRT("state propery is invalid, unable to change qml state..");
              return;
          } else {
              state.write(newState); // should reflect immediately
          }
          

          }
          @

          AFAIK as long as you provide the notify() calls of your QProperty's you can use those properties in QML too.

          1 Reply Last reply
          0
          • M Offline
            M Offline
            mario
            wrote on last edited by
            #5

            I think that you should try to solve this by having the C++ side "announcing" when is has changed to connected state.

            One way could be to set a context property:
            @
            view->rootContext()->setContextProperty("connected", mgr->isConnected());
            @
            You have to set this property each time the connection changes.

            The QML file could look something like this:

            @
            ToolButton {
            ...
            iconSource: connected ? "images/connected.png" : "images/disconnected.png"
            }
            @

            By doing this, the view controls what image should be shown when, not the C++ side.

            1 Reply Last reply
            0
            • A Offline
              A Offline
              andre
              wrote on last edited by
              #6

              First of all: I think your (Hedge) approach should work. If it does not, then that is worth digging in to further.

              On the other hand, I think that this approach is not the most elegant, and if possible, should be avoided. Instead, you can insert a QObject in your QML environment and use the property binding methods. For that to work, you need to create a QObject class like this:

              @
              class QmlCppMediator: public QObject {
              Q_OBJECT

              Q_PROPERTY (bool connected READ isConnected WRITE setConnected NOTIFY connectedChanged);

              public:
              QmlCppMediator(QObject* parent) :
              QObject(parent),
              m_connected(false) {}

              void setConnected(bool value) {m_connected = value; emit connectedChanged();}
              bool isConnected() {return m_connected;}
              

              signals:
              connectedChanged();

              private:
              bool m_connected;
              }@

              Of course, your bridge could have many more methods to interface between your QML and your C++ parts, and the properties could also be implemented in other ways. The idea is that you provide a "mediator":http://en.wikipedia.org/wiki/Mediator_pattern between your C++ and your QML.

              You can insert an instance (probably the instance) of this class using the setContextProperty method mentioned by mario above:

              @
              view->rootContext()->setContextProperty("cppInterface", m_qmlCppMediator);
              @

              You can then connect to the exposed properties like this:
              @
              ToolButton {
              ...
              iconSource: cppInterface.connected ? "images/connected.png" : "images/disconnected.png"
              }
              @
              You can of course group functionality that logically belongs together in such a mediator object, and use more than one of these.

              1 Reply Last reply
              0
              • H Offline
                H Offline
                Hedge
                wrote on last edited by
                #7

                Thanks for all your help. I implemented it as Andre said.

                It finally works.

                One error keeps bugging me though.
                I've got bq. file:///D:/MyProject/main.qml:28: ReferenceError: Can't find variable: cppInterface
                For some reasons it still works.

                That is how my main-function looks like:

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

                QmlApplicationViewer viewer;
                viewer.setOrientation(QmlApplicationViewer::ScreenOrientationAuto);
                viewer.setMainQmlFile&#40;QLatin1String("main.qml"&#41;&#41;;
                viewer.showExpanded();
                
                
                QmlCppMediator m_qmlCppMediator;
                QDeclarativeContext *context = viewer.rootContext();
                
                context->setContextProperty("cppInterface", &m_qmlCppMediator);
                m_qmlCppMediator.setConnected(true);
                
                IcecastServer icecastServer(&m_qmlCppMediator);
                
                return app.exec(&#41;;
                

                }@

                1 Reply Last reply
                0
                • M Offline
                  M Offline
                  mbrasser
                  wrote on last edited by
                  #8

                  Hi,

                  You should be able to get rid of the error by setting the context property before calling setMainQmlFile().

                  Regards,
                  Michael

                  1 Reply Last reply
                  0
                  • A Offline
                    A Offline
                    andre
                    wrote on last edited by
                    #9

                    Indeed: first setup the context with the mediator object, and then set the QML.

                    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