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. creating QML signals for C++ slots
Forum Updated to NodeBB v4.3 + New Features

creating QML signals for C++ slots

Scheduled Pinned Locked Moved Solved QML and Qt Quick
29 Posts 7 Posters 4.6k Views 4 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.
  • mzimmersM Offline
    mzimmersM Offline
    mzimmers
    wrote on last edited by
    #13

    I seem to still be missing a piece here. Various snippets:

    main.cpp

        SliderReporter sp;
        QGuiApplication app(argc, argv);
        QQmlApplicationEngine engine;
        engine.rootContext()->setContextProperty("sp", &sp);
        engine.load(url);
    

    sliderreporter.h

    class SliderReporter : public QObject
    {
        Q_OBJECT
        Q_PROPERTY(float m_value MEMBER m_value READ value WRITE setValue NOTIFY valueChanged)
    
    public:
        explicit SliderReporter(QObject *parent = nullptr);
        float value() { return m_value; }
        void setValue (float value) { m_value = value; }
    public slots:
        void reportValue(int i) {
            qDebug() << "new value of slider is:" << i;
        }
    signals:
        void valueChanged(float value);
    private:
        float m_value;
    };
    

    sliderreporter.cpp:

    SliderReporter::SliderReporter(QObject *parent)
        : QObject{parent}
    {
        QMetaObject::Connection c;
        bool b;
    
        c = QObject::connect(this, &SliderReporter::valueChanged, this, &SliderReporter::reportValue);
        b = static_cast<bool>(c);
        qDebug() << b;
    }
    

    and deep in my QLM code:

    MouseArea {
    	onReleased: sp.value = value
    

    So, I'm performing the following (I think):

    1. setting the context property in main.cpp
    2. establishing the supporting methods to the property in sliderreporter.h
    3. creating a way to "see" the signal in my SliderReporter c'tor
    4. referencing my "sp" in my QML

    What am I leaving out?

    Thanks...

    J.HilkJ 1 Reply Last reply
    0
    • mzimmersM mzimmers

      I seem to still be missing a piece here. Various snippets:

      main.cpp

          SliderReporter sp;
          QGuiApplication app(argc, argv);
          QQmlApplicationEngine engine;
          engine.rootContext()->setContextProperty("sp", &sp);
          engine.load(url);
      

      sliderreporter.h

      class SliderReporter : public QObject
      {
          Q_OBJECT
          Q_PROPERTY(float m_value MEMBER m_value READ value WRITE setValue NOTIFY valueChanged)
      
      public:
          explicit SliderReporter(QObject *parent = nullptr);
          float value() { return m_value; }
          void setValue (float value) { m_value = value; }
      public slots:
          void reportValue(int i) {
              qDebug() << "new value of slider is:" << i;
          }
      signals:
          void valueChanged(float value);
      private:
          float m_value;
      };
      

      sliderreporter.cpp:

      SliderReporter::SliderReporter(QObject *parent)
          : QObject{parent}
      {
          QMetaObject::Connection c;
          bool b;
      
          c = QObject::connect(this, &SliderReporter::valueChanged, this, &SliderReporter::reportValue);
          b = static_cast<bool>(c);
          qDebug() << b;
      }
      

      and deep in my QLM code:

      MouseArea {
      	onReleased: sp.value = value
      

      So, I'm performing the following (I think):

      1. setting the context property in main.cpp
      2. establishing the supporting methods to the property in sliderreporter.h
      3. creating a way to "see" the signal in my SliderReporter c'tor
      4. referencing my "sp" in my QML

      What am I leaving out?

      Thanks...

      J.HilkJ Online
      J.HilkJ Online
      J.Hilk
      Moderators
      wrote on last edited by
      #14

      @mzimmers

      //sliderreporter.h
      #ifndef SLIDERREPORTER_H
      #define SLIDERREPORTER_H
      
      #include <QObject>
      #include <QDebug>
      
      class SliderReporter : public QObject
      {
          Q_OBJECT
          Q_PROPERTY(float value READ value WRITE setValue NOTIFY valueChanged)
      
      public:
          explicit SliderReporter(QObject *parent = nullptr)
              : QObject{parent}
          {
              connect(this, &SliderReporter::valueChanged, this, &SliderReporter::onValueChanged);
          }
      
          [[nodiscard]] float value() const noexcept { return m_value; }
          void setValue(float newValue)
          {
              if (qFuzzyCompare(m_value , newValue))
                  return;
              m_value = newValue;
              emit valueChanged(m_value);
          }
      
      public slots:
          void setValueViaDirectCall(float value) {setValue(value);}
          /*Q_INVOKABLE <- could be added for readability, but not needed, since it is a public slot*/
          //Q_INVOKABLE void setValueViaDirectCall(float value) {setValue(value);}
      
          void onValueChanged(float newValue){
              qDebug() << Q_FUNC_INFO << newValue << "-:-" << value();
          }
      signals:
          void valueChanged(const float &value);
      
      private:
          float m_value;
      };
      
      #endif // SLIDERREPORTER_H
      
      
      //main.cpp
      #include "sliderreporter.h"
      
      int main(int argc, char *argv[])
      {
          QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
          SliderReporter sRep;
          QGuiApplication app(argc, argv);
          QQmlApplicationEngine engine;
      
          engine.rootContext()->setContextProperty("sRep", &sRep);
      
          const QUrl url(QStringLiteral("qrc:/main.qml"));
          engine.load(url);
      
      
      
          return app.exec();
      }
      
      //main.qml
      import QtQuick 2.15
      import QtQuick.Controls 2.15
      import QtQuick.Window 2.15
      import QtQuick.Layouts 1.15
      
      Window {
          id: root
          width: 800
          height: 600
          visible: true
      
          Slider {
              from: 0
              to: 100
              value: sRep.value
              onMoved: sRep.value = value // calls setValue in your cpp file when slider handle is moved
          }
      
          Timer{
              running:true
              repeat: true
              interval: 5000
              onTriggered: sRep.setValueViaDirectCall(20);
          }
      }
      

      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


      Q: What's that?
      A: It's blue light.
      Q: What does it do?
      A: It turns blue.

      GrecKoG 1 Reply Last reply
      3
      • J.HilkJ J.Hilk

        @mzimmers

        //sliderreporter.h
        #ifndef SLIDERREPORTER_H
        #define SLIDERREPORTER_H
        
        #include <QObject>
        #include <QDebug>
        
        class SliderReporter : public QObject
        {
            Q_OBJECT
            Q_PROPERTY(float value READ value WRITE setValue NOTIFY valueChanged)
        
        public:
            explicit SliderReporter(QObject *parent = nullptr)
                : QObject{parent}
            {
                connect(this, &SliderReporter::valueChanged, this, &SliderReporter::onValueChanged);
            }
        
            [[nodiscard]] float value() const noexcept { return m_value; }
            void setValue(float newValue)
            {
                if (qFuzzyCompare(m_value , newValue))
                    return;
                m_value = newValue;
                emit valueChanged(m_value);
            }
        
        public slots:
            void setValueViaDirectCall(float value) {setValue(value);}
            /*Q_INVOKABLE <- could be added for readability, but not needed, since it is a public slot*/
            //Q_INVOKABLE void setValueViaDirectCall(float value) {setValue(value);}
        
            void onValueChanged(float newValue){
                qDebug() << Q_FUNC_INFO << newValue << "-:-" << value();
            }
        signals:
            void valueChanged(const float &value);
        
        private:
            float m_value;
        };
        
        #endif // SLIDERREPORTER_H
        
        
        //main.cpp
        #include "sliderreporter.h"
        
        int main(int argc, char *argv[])
        {
            QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
            SliderReporter sRep;
            QGuiApplication app(argc, argv);
            QQmlApplicationEngine engine;
        
            engine.rootContext()->setContextProperty("sRep", &sRep);
        
            const QUrl url(QStringLiteral("qrc:/main.qml"));
            engine.load(url);
        
        
        
            return app.exec();
        }
        
        //main.qml
        import QtQuick 2.15
        import QtQuick.Controls 2.15
        import QtQuick.Window 2.15
        import QtQuick.Layouts 1.15
        
        Window {
            id: root
            width: 800
            height: 600
            visible: true
        
            Slider {
                from: 0
                to: 100
                value: sRep.value
                onMoved: sRep.value = value // calls setValue in your cpp file when slider handle is moved
            }
        
            Timer{
                running:true
                repeat: true
                interval: 5000
                onTriggered: sRep.setValueViaDirectCall(20);
            }
        }
        
        GrecKoG Offline
        GrecKoG Offline
        GrecKo
        Qt Champions 2018
        wrote on last edited by GrecKo
        #15

        @J-Hilk
        The same without the two unnecessary slots.

        connect(this, *, this, *); is kind of a non sense most of the time. Signals and slots make sense when when you don't know where the signal will be connected. To notify a change of state to the outside. Here you can just call onValueChanged internally in the setValue (wheter there's a need to keep the two separated is left as en exercise to the reader).
        Moreover exposing onValueChanged as a public slots pollutes the interface, why would you want to let the QML call it? Defining a function as slot is also not needed for the pointer to member function connect syntax. You can connect to a simple private member function (not that you should do it here).

        What's the point with setValueViaDirectCall? you can do the same with property and not add additional complexity, keeping the property syntax :

        onTriggered: sRep.value = 20

        Sorry for being negative but we don't have to make QML integration more complicated than it is and less declarative than it should be (:

        J.HilkJ 1 Reply Last reply
        2
        • GrecKoG GrecKo

          @J-Hilk
          The same without the two unnecessary slots.

          connect(this, *, this, *); is kind of a non sense most of the time. Signals and slots make sense when when you don't know where the signal will be connected. To notify a change of state to the outside. Here you can just call onValueChanged internally in the setValue (wheter there's a need to keep the two separated is left as en exercise to the reader).
          Moreover exposing onValueChanged as a public slots pollutes the interface, why would you want to let the QML call it? Defining a function as slot is also not needed for the pointer to member function connect syntax. You can connect to a simple private member function (not that you should do it here).

          What's the point with setValueViaDirectCall? you can do the same with property and not add additional complexity, keeping the property syntax :

          onTriggered: sRep.value = 20

          Sorry for being negative but we don't have to make QML integration more complicated than it is and less declarative than it should be (:

          J.HilkJ Online
          J.HilkJ Online
          J.Hilk
          Moderators
          wrote on last edited by
          #16

          @GrecKo ?

          I'm not suppling production code, but a simple example that shows the different ways one can achieve the OP's desired outcome.

          connect(this, *, this, *); is kind of a non sense most of the time. Signals and slots make sense when when you don't know where the signal will be connected. To notify a change of state to the outside. Here you can just call onValueChanged internally in the setValue (wheter there's a need to keep the two separated is left as en exercise to the reader).

          I whole hardly disagree, Property setters should do nothing but set a property and emit a signal. The c++ reaction to that changed signal can than be done in slot, that can, but doesn't have to be in the same class.

          I for example usually have one base class that contains all Properties, and one derived one, that contains the logic.

          Moreover exposing onValueChanged as a public slots pollutes the interface, why would you want to let the QML call it?

          I was to lazy to add the additional private, my bad.

          Defining a function as slot is also not needed for the pointer to member function connect syntax.

          I'm aware, but it (the intend) is still more readable, imho

          What's the point with setValueViaDirectCall? you can do the same with property and not add additional complexity, keeping the property syntax :

          onTriggered: sRep.value = 20

          again, showing an alternative.


          Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


          Q: What's that?
          A: It's blue light.
          Q: What does it do?
          A: It turns blue.

          1 Reply Last reply
          1
          • mzimmersM Offline
            mzimmersM Offline
            mzimmers
            wrote on last edited by
            #17

            Thanks for the replies, guys. I had to re-read the docs a few times to really understand what I was missing - it was an explicit call to emit() in my setValue() function. It now works more or less as I hoped.

            A few wrap-up questions, please:

            1. if I do have to explicitly emit my setValue(), what is the purpose of its mention in the Q_PROPERTY macro?
            2. if I wanted to emit the signal from QML, can I change my QML statement:
            MouseArea {
                id: trackMouse
                onReleased: sp.value = control.value
            }
            

            to something more like:

            MouseArea {
                id: trackMouse
                onReleased {
                    sp.value = control.value
                    emit sp.valueChanged
                }
            }
            

            What's the correct syntax to do something like this? And, is it even a good idea to emit the signal from QML, or should I go ahead and do it per @J-Hilk's example?
            3. The above passage is the only modification I have to make to a third-party module. It would be nice to keep this module unmodified. Is there any way I can give trackMouse this property from outside the module?

            Thank you...

            B 1 Reply Last reply
            0
            • mzimmersM mzimmers

              Thanks for the replies, guys. I had to re-read the docs a few times to really understand what I was missing - it was an explicit call to emit() in my setValue() function. It now works more or less as I hoped.

              A few wrap-up questions, please:

              1. if I do have to explicitly emit my setValue(), what is the purpose of its mention in the Q_PROPERTY macro?
              2. if I wanted to emit the signal from QML, can I change my QML statement:
              MouseArea {
                  id: trackMouse
                  onReleased: sp.value = control.value
              }
              

              to something more like:

              MouseArea {
                  id: trackMouse
                  onReleased {
                      sp.value = control.value
                      emit sp.valueChanged
                  }
              }
              

              What's the correct syntax to do something like this? And, is it even a good idea to emit the signal from QML, or should I go ahead and do it per @J-Hilk's example?
              3. The above passage is the only modification I have to make to a third-party module. It would be nice to keep this module unmodified. Is there any way I can give trackMouse this property from outside the module?

              Thank you...

              B Offline
              B Offline
              Bob64
              wrote on last edited by Bob64
              #18

              @mzimmers "if I do have to explicitly emit my setValue(), what is the purpose of its mention in the Q_PROPERTY macro?"

              The Q_PROPERTY macro is what gathers together the bits of your class interface that contribute to that property's implementation. Yes, you have to do the work to emit the signal so that there is a notification being generated, but unless you declare it in the macro, there is nothing to tell Qt that this particular signal is the one associated with that property change. Although regular naming conventions are usually used, Qt itself does not infer anything from the name. You could call the signal whatever you want.

              mzimmersM 1 Reply Last reply
              1
              • B Bob64

                @mzimmers "if I do have to explicitly emit my setValue(), what is the purpose of its mention in the Q_PROPERTY macro?"

                The Q_PROPERTY macro is what gathers together the bits of your class interface that contribute to that property's implementation. Yes, you have to do the work to emit the signal so that there is a notification being generated, but unless you declare it in the macro, there is nothing to tell Qt that this particular signal is the one associated with that property change. Although regular naming conventions are usually used, Qt itself does not infer anything from the name. You could call the signal whatever you want.

                mzimmersM Offline
                mzimmersM Offline
                mzimmers
                wrote on last edited by
                #19

                @Bob64 I'm not sure I fully understand your answer - to me, it sounds like including NOTIFY is merely bookkeeping. How (if at all) does it change the behavior of the program?

                Thanks...

                1 Reply Last reply
                0
                • fcarneyF Offline
                  fcarneyF Offline
                  fcarney
                  wrote on last edited by
                  #20

                  @mzimmers said in creating QML signals for C++ slots:

                  How (if at all) does it change the behavior of the program?

                  It is how everything in QML gets notified when a value changes. So if you did the following:

                  Text {
                    text: sp.value
                  }
                  

                  If the signal is not in the property definition "text" will never get updated. Every binding to every property in QML works this way.

                  C++ is a perfectly valid school of magic.

                  mzimmersM 1 Reply Last reply
                  2
                  • fcarneyF fcarney

                    @mzimmers said in creating QML signals for C++ slots:

                    How (if at all) does it change the behavior of the program?

                    It is how everything in QML gets notified when a value changes. So if you did the following:

                    Text {
                      text: sp.value
                    }
                    

                    If the signal is not in the property definition "text" will never get updated. Every binding to every property in QML works this way.

                    mzimmersM Offline
                    mzimmersM Offline
                    mzimmers
                    wrote on last edited by
                    #21

                    @fcarney OK, but then, why doesn't the signal fire automatically from this line?

                                onReleased: sp.value = control.value
                    
                    fcarneyF 1 Reply Last reply
                    0
                    • mzimmersM mzimmers

                      @fcarney OK, but then, why doesn't the signal fire automatically from this line?

                                  onReleased: sp.value = control.value
                      
                      fcarneyF Offline
                      fcarneyF Offline
                      fcarney
                      wrote on last edited by
                      #22

                      @mzimmers If the value is not changed it won't fire. The initial value will be read at some point. Then it will only fire if it changes.

                      I am thinking you want some other behavior in your code. What do you want to happen? Ignore the code. Are you wanting to log data periodically?

                      C++ is a perfectly valid school of magic.

                      mzimmersM 1 Reply Last reply
                      0
                      • fcarneyF fcarney

                        @mzimmers If the value is not changed it won't fire. The initial value will be read at some point. Then it will only fire if it changes.

                        I am thinking you want some other behavior in your code. What do you want to happen? Ignore the code. Are you wanting to log data periodically?

                        mzimmersM Offline
                        mzimmersM Offline
                        mzimmers
                        wrote on last edited by
                        #23

                        @fcarney said in creating QML signals for C++ slots:

                        @mzimmers If the value is not changed it won't fire. The initial value will be read at some point. Then it will only fire if it changes.

                        But when I manipulate the slider through the GUI, this signal never seems to fire. I do get the call to the setValue() function.

                        I am thinking you want some other behavior in your code. What do you want to happen? Ignore the code. Are you wanting to log data periodically?

                        No, I'm more just trying to remind myself/better understand how this mechanism works. I'll be using a lot of it in this upcoming project, and I want to get it down cold. I'm still confused on what causes the property signal to fire, as in my example, it doesn't happen merely by changing the value of the property.

                        1 Reply Last reply
                        0
                        • fcarneyF Offline
                          fcarneyF Offline
                          fcarney
                          wrote on last edited by
                          #24

                          main.cpp:

                          #include <QGuiApplication>
                          #include <QQmlApplicationEngine>
                          #include <QQmlContext>
                          #include <QDebug>
                          
                          #include "cppobject.h"
                          
                          int main(int argc, char *argv[])
                          {
                          #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
                              QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
                          #endif
                          
                              QGuiApplication app(argc, argv);
                          
                              CppObject cppobject;
                          
                              QQmlApplicationEngine engine;
                          
                              engine.rootContext()->setContextProperty("cppObject", &cppobject);
                          
                              // some connection to some object
                              cppobject.connect(&cppobject, &CppObject::valueChanged, [](float value){
                                  qDebug() << "cppObject.value changed:" << value;
                              });
                          
                              const QUrl url(QStringLiteral("qrc:/main.qml"));
                              QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                                               &app, [url](QObject *obj, const QUrl &objUrl) {
                                  if (!obj && url == objUrl)
                                      QCoreApplication::exit(-1);
                              }, Qt::QueuedConnection);
                              engine.load(url);
                          
                              return app.exec();
                          }
                          

                          main.qml:

                          import QtQuick 2.15
                          import QtQuick.Window 2.15
                          import QtQuick.Controls 2.15
                          import QtQuick.Layouts 1.15
                          
                          Window {
                              width: 640
                              height: 480
                              visible: true
                              title: qsTr("Hello World")
                          
                              ColumnLayout {
                          
                          
                                  Slider {
                                      Layout.minimumWidth: 500
                                      Layout.minimumHeight: 50
                          
                                      value: cppObject.value
                          
                                      onValueChanged: {
                                          cppObject.value = value
                                      }
                                  }
                          
                                  Text {
                                      text: cppObject.value
                                  }
                          
                              }
                          }
                          

                          cppobject.h:

                          #ifndef CPPOBJECT_H
                          #define CPPOBJECT_H
                          
                          #include <QObject>
                          
                          class CppObject : public QObject
                          {
                              Q_OBJECT
                          
                              Q_PROPERTY(float value READ value WRITE setValue NOTIFY valueChanged)
                          
                              float m_value;
                          
                          public:
                              CppObject()
                                  : m_value(0)
                              {}
                          
                              float value() const;
                              void setValue(float newValue);
                          signals:
                              void valueChanged(float value);
                          };
                          
                          inline float CppObject::value() const
                          {
                              return m_value;
                          }
                          
                          inline void CppObject::setValue(float newValue)
                          {
                              if (qFuzzyCompare(m_value, newValue))
                                  return;
                              m_value = newValue;
                              emit valueChanged(newValue);
                          }
                          
                          #endif // CPPOBJECT_H
                          

                          You can see the affect without the signal by running with it commented out.
                          For demonstration I hooked a lambda to the signal of cppobject in main.cpp.
                          This was tested in Qt 5.15.2.

                          C++ is a perfectly valid school of magic.

                          mzimmersM 1 Reply Last reply
                          2
                          • fcarneyF fcarney

                            main.cpp:

                            #include <QGuiApplication>
                            #include <QQmlApplicationEngine>
                            #include <QQmlContext>
                            #include <QDebug>
                            
                            #include "cppobject.h"
                            
                            int main(int argc, char *argv[])
                            {
                            #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
                                QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
                            #endif
                            
                                QGuiApplication app(argc, argv);
                            
                                CppObject cppobject;
                            
                                QQmlApplicationEngine engine;
                            
                                engine.rootContext()->setContextProperty("cppObject", &cppobject);
                            
                                // some connection to some object
                                cppobject.connect(&cppobject, &CppObject::valueChanged, [](float value){
                                    qDebug() << "cppObject.value changed:" << value;
                                });
                            
                                const QUrl url(QStringLiteral("qrc:/main.qml"));
                                QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                                                 &app, [url](QObject *obj, const QUrl &objUrl) {
                                    if (!obj && url == objUrl)
                                        QCoreApplication::exit(-1);
                                }, Qt::QueuedConnection);
                                engine.load(url);
                            
                                return app.exec();
                            }
                            

                            main.qml:

                            import QtQuick 2.15
                            import QtQuick.Window 2.15
                            import QtQuick.Controls 2.15
                            import QtQuick.Layouts 1.15
                            
                            Window {
                                width: 640
                                height: 480
                                visible: true
                                title: qsTr("Hello World")
                            
                                ColumnLayout {
                            
                            
                                    Slider {
                                        Layout.minimumWidth: 500
                                        Layout.minimumHeight: 50
                            
                                        value: cppObject.value
                            
                                        onValueChanged: {
                                            cppObject.value = value
                                        }
                                    }
                            
                                    Text {
                                        text: cppObject.value
                                    }
                            
                                }
                            }
                            

                            cppobject.h:

                            #ifndef CPPOBJECT_H
                            #define CPPOBJECT_H
                            
                            #include <QObject>
                            
                            class CppObject : public QObject
                            {
                                Q_OBJECT
                            
                                Q_PROPERTY(float value READ value WRITE setValue NOTIFY valueChanged)
                            
                                float m_value;
                            
                            public:
                                CppObject()
                                    : m_value(0)
                                {}
                            
                                float value() const;
                                void setValue(float newValue);
                            signals:
                                void valueChanged(float value);
                            };
                            
                            inline float CppObject::value() const
                            {
                                return m_value;
                            }
                            
                            inline void CppObject::setValue(float newValue)
                            {
                                if (qFuzzyCompare(m_value, newValue))
                                    return;
                                m_value = newValue;
                                emit valueChanged(newValue);
                            }
                            
                            #endif // CPPOBJECT_H
                            

                            You can see the affect without the signal by running with it commented out.
                            For demonstration I hooked a lambda to the signal of cppobject in main.cpp.
                            This was tested in Qt 5.15.2.

                            mzimmersM Offline
                            mzimmersM Offline
                            mzimmers
                            wrote on last edited by
                            #25

                            @fcarney thanks for the code sample. I didn't try it, because I'm sure it works.

                            I'm still not getting something: why does setValue have to emit the signal if the NOTIFY property is supposed to cause this to happen automatically when the value changes?

                            fcarneyF 1 Reply Last reply
                            0
                            • SGaistS Offline
                              SGaistS Offline
                              SGaist
                              Lifetime Qt Champion
                              wrote on last edited by
                              #26

                              Here is the issue: the NOTIFY keyword is a hint for the property system. It is still your duty to emit it at the adequate time.

                              Interested in AI ? www.idiap.ch
                              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                              1 Reply Last reply
                              2
                              • mzimmersM mzimmers

                                @fcarney thanks for the code sample. I didn't try it, because I'm sure it works.

                                I'm still not getting something: why does setValue have to emit the signal if the NOTIFY property is supposed to cause this to happen automatically when the value changes?

                                fcarneyF Offline
                                fcarneyF Offline
                                fcarney
                                wrote on last edited by
                                #27

                                @mzimmers NOTIFY tells other objects what signal fires when the property changes. It does not actually fire the signal.

                                So in QML if the cppObject.value is bound to the "text" property of Text, the code attaches to the signal specified by the NOTIFY part of Q_PROPERTY. If the NOTIFY is not specified, it doesn't know what to attach to. You will also get warnings saying the property is non-notifiable. There is a lot going on in QML property bindings.

                                It is also possible for multiple Q_PROPERTY's to use the same signal if you want them all to update when one of them changes. This might be useful to sync updates.

                                C++ is a perfectly valid school of magic.

                                1 Reply Last reply
                                2
                                • mzimmersM Offline
                                  mzimmersM Offline
                                  mzimmers
                                  wrote on last edited by
                                  #28

                                  @SGaist @fcarney thank you for the distinction; that makes sense now.

                                  So, am I correct that it's best to minimize the "work" done in the QML (in my case, with this line)

                                  onReleased: sp.value = control.value
                                  

                                  And let the C++ code handle the rest?

                                  And, as I mentioned earlier, this line is my only needed modification to a third-party module. Is there some way to "inject" this behavior from the QML that uses this Item?

                                  Thanks...

                                  1 Reply Last reply
                                  0
                                  • fcarneyF Offline
                                    fcarneyF Offline
                                    fcarney
                                    wrote on last edited by
                                    #29

                                    The only thing I can think of doing is having the c++ side read the initial value before the connection is made. That way they start in sync. Then, when it changes it will stay in sync as long at they are connected.

                                    C++ is a perfectly valid school of magic.

                                    1 Reply Last reply
                                    1

                                    • Login

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