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. Pass and modify C++ data from a Custom QML Item
QtWS25 Last Chance

Pass and modify C++ data from a Custom QML Item

Scheduled Pinned Locked Moved QML and Qt Quick
c++custom itemqmlproperty
4 Posts 2 Posters 1.6k 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.
  • F Offline
    F Offline
    Fred Waltzer
    wrote on last edited by
    #1

    I would like to pass "simply" a variable (defined in a C++ class, shared to QML with "rootContext()->setContextProperty()" ) to a QML Button and modify it on the OnClick event.
    The OnClick event of the CustomBtn would increment the c++ variable with 1.

    // -------------- main.qml --------------

    import QtQuick 2.2
    import QtQuick.Controls 1.1
    
    ApplicationWindow {
        visible: true
        width: 640
        height: 480
        title: qsTr("Hello World")
    
        CustomBtn
        {
            id: aCustomBtn
            myQMLVar: MyQMLObject.value;
        }
    
        Button {
            width: 100
            height: 62
    
            text: "+2"
            onClicked:  {
                MyQMLObject.value = MyQMLObject.value+2
            }
    
            anchors.left: aCustomBtn.right
            anchors.top: aCustomBtn.top
        }
    }
    

    // -------------- CustomBtn.qml --------------

    import QtQuick 2.0
    import QtQuick.Controls 1.1
    
    Item {
        width: 100
        height: 62
    
        property var myQMLVar
    
        Button {
            anchors.fill: parent
            text: "+1"
            onClicked: {
                myQMLVar = myQMLVar+1
            }
        }
    }
    

    // -------------- main.cpp --------------

    #include <QApplication>
    #include <QQmlApplicationEngine>
    #include <QQmlContext>
    #include "myobject.h"
    
    int main(int argc, char *argv[])
    {
        QApplication app(argc, argv);
        MyObject anObj;
    
        QQmlApplicationEngine engine;
        engine.rootContext()->setContextProperty("MyQMLObject", &anObj);
        engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
    
        return app.exec();
    }
    

    // -------------- myobject.h --------------

    #ifndef MYOBJECT_H
    #define MYOBJECT_H
    
    #include <QDebug>
    #include <QObject>
    #include <QVariant>
    
    class MyObject : public QObject
    {
        Q_OBJECT
        Q_PROPERTY(QVariant value READ value WRITE setValue NOTIFY valueChanged)
    
    public:
        explicit MyObject(QObject *parent = 0);
    
        QVariant value() const {
            return m_value;
        }
    
    signals:
        void valueChanged(QVariant arg);
    
    public slots:
        void setValue(QVariant arg) {
            if (m_value != arg) {
                m_value = arg;
                qDebug() << "m_value:" << m_value;
                emit valueChanged(arg);
            }
        }
    
    private:
        QVariant m_value;
    };
    
    #endif // MYOBJECT_H
    

    Create a QtQuick project and include the code above, the "+1" CustomBtn does not increment the C++ variable, when the "+2" normal button increments it.
    Did the "myQMLVar" property is correctly defined in the CustomBtn?

    Is it just impossible to do it this way ?

    Will I have to copy paste the code from the CustomBtn calling directly "MyObject.value" for each different C++ variable that I want to modify this way ?

    p3c0P 1 Reply Last reply
    0
    • F Fred Waltzer

      I would like to pass "simply" a variable (defined in a C++ class, shared to QML with "rootContext()->setContextProperty()" ) to a QML Button and modify it on the OnClick event.
      The OnClick event of the CustomBtn would increment the c++ variable with 1.

      // -------------- main.qml --------------

      import QtQuick 2.2
      import QtQuick.Controls 1.1
      
      ApplicationWindow {
          visible: true
          width: 640
          height: 480
          title: qsTr("Hello World")
      
          CustomBtn
          {
              id: aCustomBtn
              myQMLVar: MyQMLObject.value;
          }
      
          Button {
              width: 100
              height: 62
      
              text: "+2"
              onClicked:  {
                  MyQMLObject.value = MyQMLObject.value+2
              }
      
              anchors.left: aCustomBtn.right
              anchors.top: aCustomBtn.top
          }
      }
      

      // -------------- CustomBtn.qml --------------

      import QtQuick 2.0
      import QtQuick.Controls 1.1
      
      Item {
          width: 100
          height: 62
      
          property var myQMLVar
      
          Button {
              anchors.fill: parent
              text: "+1"
              onClicked: {
                  myQMLVar = myQMLVar+1
              }
          }
      }
      

      // -------------- main.cpp --------------

      #include <QApplication>
      #include <QQmlApplicationEngine>
      #include <QQmlContext>
      #include "myobject.h"
      
      int main(int argc, char *argv[])
      {
          QApplication app(argc, argv);
          MyObject anObj;
      
          QQmlApplicationEngine engine;
          engine.rootContext()->setContextProperty("MyQMLObject", &anObj);
          engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
      
          return app.exec();
      }
      

      // -------------- myobject.h --------------

      #ifndef MYOBJECT_H
      #define MYOBJECT_H
      
      #include <QDebug>
      #include <QObject>
      #include <QVariant>
      
      class MyObject : public QObject
      {
          Q_OBJECT
          Q_PROPERTY(QVariant value READ value WRITE setValue NOTIFY valueChanged)
      
      public:
          explicit MyObject(QObject *parent = 0);
      
          QVariant value() const {
              return m_value;
          }
      
      signals:
          void valueChanged(QVariant arg);
      
      public slots:
          void setValue(QVariant arg) {
              if (m_value != arg) {
                  m_value = arg;
                  qDebug() << "m_value:" << m_value;
                  emit valueChanged(arg);
              }
          }
      
      private:
          QVariant m_value;
      };
      
      #endif // MYOBJECT_H
      

      Create a QtQuick project and include the code above, the "+1" CustomBtn does not increment the C++ variable, when the "+2" normal button increments it.
      Did the "myQMLVar" property is correctly defined in the CustomBtn?

      Is it just impossible to do it this way ?

      Will I have to copy paste the code from the CustomBtn calling directly "MyObject.value" for each different C++ variable that I want to modify this way ?

      p3c0P Offline
      p3c0P Offline
      p3c0
      Moderators
      wrote on last edited by p3c0
      #2

      Hi @Fred-Waltzer,
      Binding doesn't work in reverse order i.e updating myQMLVar wont re-evaluate the expression and thus it won't update MyQMLObject.
      One way would be to update MyQMLObject in myQMLVar handler viz. onMyQMLVarChanged but you may get binding loop.
      BTW, Since you have set MyQMLObject as context property it will be directly accessible in CustomBtn too.

      157

      1 Reply Last reply
      0
      • F Offline
        F Offline
        Fred Waltzer
        wrote on last edited by
        #3

        Thanks for the answer, that was my biggest fear.
        That is exactly what I didn't want to do...
        Copy+Paste QML code for each CustomBtn and which will modify a different C++ variable.

        Didn't they think about factorizing code when they wrote the QML and C++ bindings ?
        If anyone found a solution other than COPY-PASTE, I'll be glad to hear about it.

        p3c0P 1 Reply Last reply
        0
        • F Fred Waltzer

          Thanks for the answer, that was my biggest fear.
          That is exactly what I didn't want to do...
          Copy+Paste QML code for each CustomBtn and which will modify a different C++ variable.

          Didn't they think about factorizing code when they wrote the QML and C++ bindings ?
          If anyone found a solution other than COPY-PASTE, I'll be glad to hear about it.

          p3c0P Offline
          p3c0P Offline
          p3c0
          Moderators
          wrote on last edited by
          #4

          @Fred-Waltzer MyQMLObject will be available in all the QML files of the project. So no need to create different C++ variable.

          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