Setting the value of a user defined property
-
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?
-
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?
-
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?
@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); -
@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);@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.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?
@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); -
@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);@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.
-
@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.
-
@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.
@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
qOverloadif you have C++14 support, orQOverloadotherwise. -