How to Bind a QML Property to a C++ Function: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
No edit summary
 
No edit summary
Line 1: Line 1:
=Binding a <span class="caps">QML</span> property to a C++ function=
[[Category:HowTo]]<br />[[Category:Developing_with_Qt::General]]<br />[[Category:Tutorial]]


At the moment Qt Quick does not provide an implementation for linking a <span class="caps">QML</span> property to the result of a C++ function. There exists a suggestion for adding support for this [https://bugreports.qt.nokia.com//browse/QTBUG-17323 here] ''[bugreports.qt.nokia.com]'' though.
[toc align_right=&quot;yes&amp;quot; depth=&quot;2&amp;quot;]


In this article we will show how to make binding of properties to C++ functions work using [http://doc.qt.nokia.com/latest/qobject.html#Q_PROPERTY Q_PROPERTY] ''[doc.qt.nokia.com]'' with a [http://doc.qt.nokia.com/latest/properties.html#qt-s-property-system <span class="caps">NOTIFY</span>] ''[doc.qt.nokia.com]'' signal that is emitted whenever the value of the property changes.
= Binding a QML property to a C++ function =


==The C++ implementation==
At the moment Qt Quick does not provide an implementation for linking a QML property to the result of a C++ function. There exists a suggestion for adding support for this &quot;here&amp;quot;:https://bugreports.qt.nokia.com//browse/QTBUG-17323 though.


In the Object class in the example below we create a Q_PROPERTY that is used to set and update the text in the <span class="caps">QML</span> code and that has a changeOfStatus() signal which is emitted whenever the status of the C++ function someFunction() changes:
In this article we will show how to make binding of properties to C++ functions work using &quot;Q_PROPERTY&amp;quot;:http://doc.qt.nokia.com/latest/qobject.html#Q_PROPERTY with a &quot;NOTIFY&amp;quot;:http://doc.qt.nokia.com/latest/properties.html#qt-s-property-system signal that is emitted whenever the value of the property changes.


The Object::getTheChange() function sets the text of the <span class="caps">QML</span> item depending on the result of Object::someFunction(). The result is set as the value of the text property in the <span class="caps">QML</span> code.
== The C++ implementation ==


Object::someFunction() is callable from <span class="caps">QML</span> as it uses [http://doc.qt.nokia.com/latest/qobject.html#Q_INVOKABLE Q_INVOKABLE] ''[doc.qt.nokia.com]''. It simply changes the status of a member variable and is called every 5 seconds using a [http://doc.qt.nokia.com/latest/qtimer.html QTimer] ''[doc.qt.nokia.com]'' to illustrate how the <span class="caps">QML</span> property is able to react to the changes of this function. It can also be called from the <span class="caps">QML</span> code when clicking the text. At the end it emits the changeOfStatus() signal which triggers Object::getTheChange() to be called and the text to be reevaluated.
In the Object class in the example below we create a Q_PROPERTY that is used to set and update the text in the QML code and that has a changeOfStatus() signal which is emitted whenever the status of the C++ function someFunction() changes:


main.cpp<br />
<code>Q_PROPERTY(QString theChange READ getTheChange NOTIFY changeOfStatus)<code>


==The <span class="caps">QML</span> implementation==
The Object::getTheChange() function sets the text of the QML item depending on the result of Object::someFunction(). The result is set as the value of the text property in the QML code.


In the <span class="caps">QML</span> code below we create a [http://doc.qt.nokia.com/latest/qml-rectangle.html Rectangle] ''[doc.qt.nokia.com]'' that reacts to mouse clicks. The text is set to the the result of the Object::theChange() function.
Object::someFunction() is callable from QML as it uses &quot;Q_INVOKABLE&amp;quot;:http://doc.qt.nokia.com/latest/qobject.html#Q_INVOKABLE. It simply changes the status of a member variable and is called every 5 seconds using a &quot;QTimer&amp;quot;:http://doc.qt.nokia.com/latest/qtimer.html to illustrate how the QML property is able to react to the changes of this function. It can also be called from the QML code when clicking the text. At the end it emits the changeOfStatus() signal which triggers Object::getTheChange() to be called and the text to be reevaluated.
 
main.cpp<br /></code><br />#include &lt;QtGui&amp;gt;<br />#include &lt;QtDeclarative&amp;gt;
 
class Object : public QObject<br />{<br /> Q_OBJECT<br /> Q_PROPERTY(QString theChange READ getTheChange NOTIFY changeOfStatus)
 
public:<br /> Object()<br /> {<br /> changeMe = false;<br /> myTimer = new QTimer(this);<br /> myTimer-&gt;start(5000);<br /> connect(myTimer, SIGNAL (timeout()), this, SLOT (testSlot()));<br /> }
 
QString getTheChange()<br /> {<br /> if (theValue  0)
  &amp;#123;
  return &amp;quot;The text changed&amp;quot;;
  &amp;#125;
  if (theValue  1)<br /> {<br /> return &quot;New text change&amp;quot;;<br /> }<br /> return &quot;nothing has happened yet&amp;quot;;
 
}
 
Q_INVOKABLE void someFunction(int i)<br /> {<br /> if ( i  0) &amp;#123;
  theValue = 0;
  &amp;#125;
  if (i  1) {<br /> theValue = 1;<br /> }
 
emit changeOfStatus(i);<br /> }
 
signals:<br /> void changeOfStatus(int i) ;<br /> public slots:<br /> void testSlot()<br /> {<br /> if (changeMe)<br /> {<br /> someFunction(0);<br /> } else {<br /> someFunction(1);<br /> }<br /> changeMe = !changeMe;<br /> }
 
private:<br /> bool changeMe;<br /> int theValue;<br /> QTimer '''myTimer;
<br />};
<br />#include &quot;main.moc&amp;quot;
<br />int main(int argc, char'''* argv)<br />{<br /> QApplication app(argc, argv);<br /> Object myObj;<br /> QDeclarativeView view;<br /> view.rootContext()-&gt;setContextProperty(&quot;rootItem&amp;quot;, (QObject *)&amp;myObj);<br /> view.setSource(QUrl::fromLocalFile&amp;amp;#40;&quot;main.qml&amp;quot;&amp;#41;);<br /> view.show();<br /> return app.exec&amp;amp;#40;&amp;#41;;
 
}
 
<code>
 
== The QML implementation ==
 
In the QML code below we create a &quot;Rectangle&amp;quot;:http://doc.qt.nokia.com/latest/qml-rectangle.html that reacts to mouse clicks. The text is set to the the result of the Object::theChange() function.


main.qml
main.qml


So, using the approach in the example above, we get a way for <span class="caps">QML</span> properties to react to changes that happen internally in the C++ code.
</code><br />import QtQuick 1.0
 
Rectangle {<br /> width: 440; height: 150
 
Column {<br /> anchors.fill: parent; spacing: 20
 
Text {<br /> text: rootItem.theChange<br /> font.pointSize: 25; anchors.horizontalCenter: parent.horizontalCenter
 
}<br /> }<br />}


===Categories:===
<code>


* [[:Category:Developing with Qt|Developing_with_Qt]]
So, using the approach in the example above, we get a way for QML properties to react to changes that happen internally in the C++ code.
** [[:Category:Developing with Qt::General|General]]
* [[:Category:HowTo|HowTo]]
* [[:Category:Tutorial|Tutorial]]

Revision as of 14:44, 23 February 2015



[toc align_right="yes&quot; depth="2&quot;]

Binding a QML property to a C++ function

At the moment Qt Quick does not provide an implementation for linking a QML property to the result of a C++ function. There exists a suggestion for adding support for this "here&quot;:https://bugreports.qt.nokia.com//browse/QTBUG-17323 though.

In this article we will show how to make binding of properties to C++ functions work using "Q_PROPERTY&quot;:http://doc.qt.nokia.com/latest/qobject.html#Q_PROPERTY with a "NOTIFY&quot;:http://doc.qt.nokia.com/latest/properties.html#qt-s-property-system signal that is emitted whenever the value of the property changes.

The C++ implementation

In the Object class in the example below we create a Q_PROPERTY that is used to set and update the text in the QML code and that has a changeOfStatus() signal which is emitted whenever the status of the C++ function someFunction() changes:

Q_PROPERTY(QString theChange READ getTheChange NOTIFY changeOfStatus)<code>

The Object::getTheChange() function sets the text of the QML item depending on the result of Object::someFunction(). The result is set as the value of the text property in the QML code.

Object::someFunction() is callable from QML as it uses &quot;Q_INVOKABLE&amp;quot;:http://doc.qt.nokia.com/latest/qobject.html#Q_INVOKABLE. It simply changes the status of a member variable and is called every 5 seconds using a &quot;QTimer&amp;quot;:http://doc.qt.nokia.com/latest/qtimer.html to illustrate how the QML property is able to react to the changes of this function. It can also be called from the QML code when clicking the text. At the end it emits the changeOfStatus() signal which triggers Object::getTheChange() to be called and the text to be reevaluated.

main.cpp<br />


#include <QtGui&gt;
#include <QtDeclarative&gt;

class Object : public QObject
{
Q_OBJECT
Q_PROPERTY(QString theChange READ getTheChange NOTIFY changeOfStatus)

public:
Object()
{
changeMe = false;
myTimer = new QTimer(this);
myTimer->start(5000);
connect(myTimer, SIGNAL (timeout()), this, SLOT (testSlot()));
}

QString getTheChange()
{
if (theValue 0)

 &#123;
  return &quot;The text changed&quot;;
 &#125;
 if (theValue  1)
{
return "New text change&quot;;
}
return "nothing has happened yet&quot;;

}

Q_INVOKABLE void someFunction(int i)
{
if ( i 0) &#123;

  theValue = 0;
 &#125;
 if (i  1) {
theValue = 1;
}

emit changeOfStatus(i);
}

signals:
void changeOfStatus(int i) ;
public slots:
void testSlot()
{
if (changeMe)
{
someFunction(0);
} else {
someFunction(1);
}
changeMe = !changeMe;
}

private:
bool changeMe;
int theValue;
QTimer myTimer;
};
#include "main.moc&quot;
int main(int argc, char* argv)
{
QApplication app(argc, argv);
Object myObj;
QDeclarativeView view;
view.rootContext()->setContextProperty("rootItem&quot;, (QObject *)&myObj);
view.setSource(QUrl::fromLocalFile&amp;#40;"main.qml&quot;&#41;);
view.show();
return app.exec&amp;#40;&#41;;

}

== The QML implementation ==

In the QML code below we create a &quot;Rectangle&amp;quot;:http://doc.qt.nokia.com/latest/qml-rectangle.html that reacts to mouse clicks. The text is set to the the result of the Object::theChange() function.

main.qml


import QtQuick 1.0

Rectangle {
width: 440; height: 150

Column {
anchors.fill: parent; spacing: 20

Text {
text: rootItem.theChange
font.pointSize: 25; anchors.horizontalCenter: parent.horizontalCenter

}
}
}

So, using the approach in the example above, we get a way for QML properties to react to changes that happen internally in the C++ code.