Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Setting the value of a user defined property
Forum Updated to NodeBB v4.3 + New Features

Setting the value of a user defined property

Scheduled Pinned Locked Moved Solved General and Desktop
9 Posts 3 Posters 1.6k Views 2 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.
  • O Offline
    O Offline
    ofmrew
    wrote on last edited by
    #1

    I have (I believe) created a property, tval, but I cannot set its value.

    class MyCanvas : public QWidget
    {
        Q_OBJECT
        Q_PROPERTY(double tval READ tval WRITE setTval)
    public:
        explicit MyCanvas(QWidget *parent = nullptr);
        void paintEvent(QPaintEvent *e);
        void setTval(double);
        double tval();
        QPropertyAnimation *animation;
    };
    void MyCanvas::setTval(double tv)
    {
        tval = tv;
    }
    /home/xxx/AnimatedEllipse/mycanvas.cpp:16: error: invalid use of member function (did you forget the ‘()’ ?)
         tval = tv;
              ^
    

    What is wrong?

    O J.HilkJ 2 Replies Last reply
    0
    • O ofmrew

      I have (I believe) created a property, tval, but I cannot set its value.

      class MyCanvas : public QWidget
      {
          Q_OBJECT
          Q_PROPERTY(double tval READ tval WRITE setTval)
      public:
          explicit MyCanvas(QWidget *parent = nullptr);
          void paintEvent(QPaintEvent *e);
          void setTval(double);
          double tval();
          QPropertyAnimation *animation;
      };
      void MyCanvas::setTval(double tv)
      {
          tval = tv;
      }
      /home/xxx/AnimatedEllipse/mycanvas.cpp:16: error: invalid use of member function (did you forget the ‘()’ ?)
           tval = tv;
                ^
      

      What is wrong?

      O Offline
      O Offline
      ofmrew
      wrote on last edited by
      #2

      @ofmrew I added:

      private:
          double m_tval{0.0};
      

      And it compiles and executes. I take it that you must supply the m_name.

      1 Reply Last reply
      0
      • O ofmrew

        I have (I believe) created a property, tval, but I cannot set its value.

        class MyCanvas : public QWidget
        {
            Q_OBJECT
            Q_PROPERTY(double tval READ tval WRITE setTval)
        public:
            explicit MyCanvas(QWidget *parent = nullptr);
            void paintEvent(QPaintEvent *e);
            void setTval(double);
            double tval();
            QPropertyAnimation *animation;
        };
        void MyCanvas::setTval(double tv)
        {
            tval = tv;
        }
        /home/xxx/AnimatedEllipse/mycanvas.cpp:16: error: invalid use of member function (did you forget the ‘()’ ?)
             tval = tv;
                  ^
        

        What is wrong?

        J.HilkJ Offline
        J.HilkJ Offline
        J.Hilk
        Moderators
        wrote on last edited by
        #3

        @ofmrew you'll run into serve issues if you leave that class as it is!!!

        Let me suggest some differences:

        class MyCanvas : public QWidget
        {
            Q_OBJECT
            Q_PROPERTY(double tval READ tval WRITE setTval NOTIFY tvalChanged)
        public:
            explicit MyCanvas(QWidget *parent = nullptr);
            void paintEvent(QPaintEvent *e);
            void setTval(double);
            double tval();
            QPropertyAnimation *animation;
        };
        void MyCanvas::setTval(double tv)
        {
            if(tv != m_tVal){
                m_tVal = tv;
                emit tvalChanged();
            }
        }
        
        inline const double &tval(){return m_tVal;} 
        
        signals:
           void tvalChanged();
        
        
        private: 
            double m_tVal = (0.0);
        

        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.

        O 1 Reply Last reply
        2
        • J.HilkJ J.Hilk

          @ofmrew you'll run into serve issues if you leave that class as it is!!!

          Let me suggest some differences:

          class MyCanvas : public QWidget
          {
              Q_OBJECT
              Q_PROPERTY(double tval READ tval WRITE setTval NOTIFY tvalChanged)
          public:
              explicit MyCanvas(QWidget *parent = nullptr);
              void paintEvent(QPaintEvent *e);
              void setTval(double);
              double tval();
              QPropertyAnimation *animation;
          };
          void MyCanvas::setTval(double tv)
          {
              if(tv != m_tVal){
                  m_tVal = tv;
                  emit tvalChanged();
              }
          }
          
          inline const double &tval(){return m_tVal;} 
          
          signals:
             void tvalChanged();
          
          
          private: 
              double m_tVal = (0.0);
          
          O Offline
          O Offline
          ofmrew
          wrote on last edited by
          #4

          @J.Hilk My program works, it is:

          #define MYCANVAS_H
          
          #include <QWidget>
          #include <QPaintEvent>
          #include <QPropertyAnimation>
          #include <QPainter>
          #include <QVariant>
          #include <QtMath>
          #include <QDebug>
          
          class MyCanvas : public QWidget
          {
              Q_OBJECT
              Q_PROPERTY(double tval READ tval WRITE setTval)
          public:
              explicit MyCanvas(QWidget *parent = nullptr);
              void paintEvent(QPaintEvent *e);
              void setTval(double);
              double tval();
              QPropertyAnimation *animation;
          private:
              double m_tval{0.0};
          signals:
          public slots:
              void animationStart();
          };
          MyCanvas::MyCanvas(QWidget *parent) : QWidget(parent)
          {
              animation = new QPropertyAnimation(this, "tval");
              animation->setDuration(10000);
              animation->setStartValue(0.0);
              animation->setEndValue(M_PI * 2.0);
          }
          
          void MyCanvas::paintEvent(QPaintEvent *e)
          {
              QPainter p(this);
              qreal xAxis = 1000.0;
              qreal yAxis = 400.0;
              QRectF rectEllipse(-xAxis * 0.5, -yAxis * 0.5, xAxis, yAxis);
              QPoint center = this->rect().center();
              p.translate(center);
              p.drawRect(rectEllipse);
              p.drawEllipse(-xAxis * 0.5, -yAxis * 0.5, xAxis, yAxis);
              p.drawEllipse(-xAxis * 0.5, -yAxis * 0.5, 5.0, 5.0);
              QPointF pe(xAxis * qCos(this->tval()), yAxis * qSin(this->tval()));
              qDebug() << pe;
              p.drawEllipse(pe * 0.5, 5.0, 5.0);
              p.drawLine(QPointF(0.0, 0.0), pe * 0.5);
              p.drawLine(QPointF(0.0, 0.0), 200.0 * QPointF(qCos(this->tval()), qSin(this->tval())));
          }
          
          void MyCanvas::setTval(double tv)
          {
              m_tval = tv;
              this->update();
          }
          
          double MyCanvas::tval()
          {
              return m_tval;
          }
          
          void MyCanvas::animationStart()
          {
              animation->start();
          }
          

          I use this->update() to cause the drawing instead of tvalChanged(). Will this be problematic?

          J.HilkJ 1 Reply Last reply
          0
          • O ofmrew

            @J.Hilk My program works, it is:

            #define MYCANVAS_H
            
            #include <QWidget>
            #include <QPaintEvent>
            #include <QPropertyAnimation>
            #include <QPainter>
            #include <QVariant>
            #include <QtMath>
            #include <QDebug>
            
            class MyCanvas : public QWidget
            {
                Q_OBJECT
                Q_PROPERTY(double tval READ tval WRITE setTval)
            public:
                explicit MyCanvas(QWidget *parent = nullptr);
                void paintEvent(QPaintEvent *e);
                void setTval(double);
                double tval();
                QPropertyAnimation *animation;
            private:
                double m_tval{0.0};
            signals:
            public slots:
                void animationStart();
            };
            MyCanvas::MyCanvas(QWidget *parent) : QWidget(parent)
            {
                animation = new QPropertyAnimation(this, "tval");
                animation->setDuration(10000);
                animation->setStartValue(0.0);
                animation->setEndValue(M_PI * 2.0);
            }
            
            void MyCanvas::paintEvent(QPaintEvent *e)
            {
                QPainter p(this);
                qreal xAxis = 1000.0;
                qreal yAxis = 400.0;
                QRectF rectEllipse(-xAxis * 0.5, -yAxis * 0.5, xAxis, yAxis);
                QPoint center = this->rect().center();
                p.translate(center);
                p.drawRect(rectEllipse);
                p.drawEllipse(-xAxis * 0.5, -yAxis * 0.5, xAxis, yAxis);
                p.drawEllipse(-xAxis * 0.5, -yAxis * 0.5, 5.0, 5.0);
                QPointF pe(xAxis * qCos(this->tval()), yAxis * qSin(this->tval()));
                qDebug() << pe;
                p.drawEllipse(pe * 0.5, 5.0, 5.0);
                p.drawLine(QPointF(0.0, 0.0), pe * 0.5);
                p.drawLine(QPointF(0.0, 0.0), 200.0 * QPointF(qCos(this->tval()), qSin(this->tval())));
            }
            
            void MyCanvas::setTval(double tv)
            {
                m_tval = tv;
                this->update();
            }
            
            double MyCanvas::tval()
            {
                return m_tval;
            }
            
            void MyCanvas::animationStart()
            {
                animation->start();
            }
            

            I use this->update() to cause the drawing instead of tvalChanged(). Will this be problematic?

            J.HilkJ Offline
            J.HilkJ Offline
            J.Hilk
            Moderators
            wrote on last edited by
            #5

            @ofmrew said in Setting the value of a user defined property:

            I use this->update() to cause the drawing instead of tvalChanged(). Will this be problematic?

            Well that depends entierly on what you else your property is going to do.

            If you have anything bound to it in a QML-file than that will never get updated, as there's no notify signal.

            Also you always update and do not check if the value actually changes before hand. That will lead to a binding loop if you would actually emit a Signal.

            Just for ease of mind and to be compliant to the Qt standart I would at least make the following change to setTval:

            //in your constructor
            MyCanvas::MyCanvas (QWidget *parent ) : QWidget(parent)
            {
                connect(this, &MyCanvas::tvalChanged, this, &MyCanvas::update);
            }
            
            void MyCanvas::setTval(double tv)
             {
                 if(m_tval != tv)
                 {
                     m_tval = tv;
                     emit tvalChanged();
                 }
            }
            

            if you only want to call update() from a qml-file, than a QProperty is actually the wrong method you can call functions directly from qml.

            //MyCanvas.h
            Q_INVOKABLE void changeValue(double value);
            

            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.

            O 1 Reply Last reply
            0
            • J.HilkJ J.Hilk

              @ofmrew said in Setting the value of a user defined property:

              I use this->update() to cause the drawing instead of tvalChanged(). Will this be problematic?

              Well that depends entierly on what you else your property is going to do.

              If you have anything bound to it in a QML-file than that will never get updated, as there's no notify signal.

              Also you always update and do not check if the value actually changes before hand. That will lead to a binding loop if you would actually emit a Signal.

              Just for ease of mind and to be compliant to the Qt standart I would at least make the following change to setTval:

              //in your constructor
              MyCanvas::MyCanvas (QWidget *parent ) : QWidget(parent)
              {
                  connect(this, &MyCanvas::tvalChanged, this, &MyCanvas::update);
              }
              
              void MyCanvas::setTval(double tv)
               {
                   if(m_tval != tv)
                   {
                       m_tval = tv;
                       emit tvalChanged();
                   }
              }
              

              if you only want to call update() from a qml-file, than a QProperty is actually the wrong method you can call functions directly from qml.

              //MyCanvas.h
              Q_INVOKABLE void changeValue(double value);
              
              O Offline
              O Offline
              ofmrew
              wrote on last edited by
              #6

              @J.Hilk Compiler error! mycanvas.cpp:9: error: no matching function for call to ‘MyCanvas::connect(MyCanvas*, void (MyCanvas::)(), MyCanvas, <unresolved overloaded function type>)’
              connect(this, &MyCanvas::tvalChanged, this, &MyCanvas::update);

              It cannot resolve the over loaded update() function; however, this->update() give on error. Is there a way around this or must I create a new method that simply calls update()? Also, from the documentation it would appear that adding NOTIFY tvalChanged in the .h does nothing in a C++ program, it is there only for QML, which I do not use.

              O JKSHJ 2 Replies Last reply
              0
              • O ofmrew

                @J.Hilk Compiler error! mycanvas.cpp:9: error: no matching function for call to ‘MyCanvas::connect(MyCanvas*, void (MyCanvas::)(), MyCanvas, <unresolved overloaded function type>)’
                connect(this, &MyCanvas::tvalChanged, this, &MyCanvas::update);

                It cannot resolve the over loaded update() function; however, this->update() give on error. Is there a way around this or must I create a new method that simply calls update()? Also, from the documentation it would appear that adding NOTIFY tvalChanged in the .h does nothing in a C++ program, it is there only for QML, which I do not use.

                O Offline
                O Offline
                ofmrew
                wrote on last edited by
                #7

                @ofmrew Lambda function to the rescue, namely:
                connect(this, &MyCanvas::tvalChanged, = {this->update();});
                The more I use Lambdas the more I like them!
                Now it works with all of your changes added including NOTIFY tvalChanged so QML is happy.
                One more question: Why the inline for tval()?

                J.HilkJ 1 Reply Last reply
                1
                • O ofmrew

                  @J.Hilk Compiler error! mycanvas.cpp:9: error: no matching function for call to ‘MyCanvas::connect(MyCanvas*, void (MyCanvas::)(), MyCanvas, <unresolved overloaded function type>)’
                  connect(this, &MyCanvas::tvalChanged, this, &MyCanvas::update);

                  It cannot resolve the over loaded update() function; however, this->update() give on error. Is there a way around this or must I create a new method that simply calls update()? Also, from the documentation it would appear that adding NOTIFY tvalChanged in the .h does nothing in a C++ program, it is there only for QML, which I do not use.

                  JKSHJ Offline
                  JKSHJ Offline
                  JKSH
                  Moderators
                  wrote on last edited by JKSH
                  #8

                  @ofmrew said in Setting the value of a user defined property:

                  It cannot resolve the over loaded update() function

                  To connect an overloaded function, see http://doc.qt.io/qt-5/signalsandslots-syntaxes.html#selecting-overloaded-signals-and-slots

                  I recomment qOverload if you have C++14 support, or QOverload otherwise.

                  Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                  1 Reply Last reply
                  2
                  • O ofmrew

                    @ofmrew Lambda function to the rescue, namely:
                    connect(this, &MyCanvas::tvalChanged, = {this->update();});
                    The more I use Lambdas the more I like them!
                    Now it works with all of your changes added including NOTIFY tvalChanged so QML is happy.
                    One more question: Why the inline for tval()?

                    J.HilkJ Offline
                    J.HilkJ Offline
                    J.Hilk
                    Moderators
                    wrote on last edited by J.Hilk
                    #9

                    @ofmrew
                    hey, I'm glad you made it work.

                    One more question: Why the inline for tval()?

                    Well,... habid. I believe a function defined entirely inside a class is implicitly an inline function.


                    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
                    0

                    • Login

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