How to use a C class declared in a namespace with Q PROPERTY and QML: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
No edit summary
No edit summary
Line 1: Line 1:
[[Category:HowTo]]<br />[[Category:Developing_with_Qt::General]]<br />[[Category:Tutorial]]
[[Category:HowTo]]
[[Category:Developing_with_Qt::General]]
[[Category:Tutorial]]


'''English''' [[:How_to_use_a_C_class_declared_in_a_namespace_with_Q_PROPERTY_and_QML_Bulgarian|Български]]
'''English''' [[:How_to_use_a_C_class_declared_in_a_namespace_with_Q_PROPERTY_and_QML_Bulgarian|Български]]


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


= How to use a C++ class declared in a namespace with Q_PROPERTY and QML =
= How to use a C++ class declared in a namespace with Q_PROPERTY and QML =


Using a C++ class declared in a namespace with QML works out of the box, in general. All you need to do is to ensure that you register the class for usage in QML with &quot;qmlRegisterType()&quot;:http://doc.qt.nokia.com/latest/qdeclarativeengine.html#qmlRegisterType. When you need to reference the namespaced class in a &quot;Q_PROPERTY&amp;quot;:http://doc.qt.nokia.com/latest/qobject.html#Q_PROPERTY however, then there are some concerns that need to be taken for this to work with QML. The example below illustrate the steps that need to be taken.
Using a C++ class declared in a namespace with QML works out of the box, in general. All you need to do is to ensure that you register the class for usage in QML with "qmlRegisterType()":http://doc.qt.nokia.com/latest/qdeclarativeengine.html#qmlRegisterType. When you need to reference the namespaced class in a "Q_PROPERTY":http://doc.qt.nokia.com/latest/qobject.html#Q_PROPERTY however, then there are some concerns that need to be taken for this to work with QML. The example below illustrate the steps that need to be taken.


== A Simple Example ==
== A Simple Example ==
Line 13: Line 15:
The example below consists of 2 classes declared in a namespace:
The example below consists of 2 classes declared in a namespace:


<code>MyNamespace::Person<br />PartyNamespace::BirthdayParty </code>
<code>MyNamespace::Person
PartyNamespace::BirthdayParty </code>


The Person class is referenced in the Q_PROPERTY declaration of the BirthdayParty class. In order for the QML code using the classes to work as expected, then the namespace name has to be included when referring to the Person class in Q_PROPERTY declarations and in associated read and write function prototypes and also in &quot;Q_INVOKABLE&amp;quot;:http://doc.qt.nokia.com/latest/qobject.html#Q_INVOKABLE function prototypes. In general, C++ does not have this kind of limitation; it is enough that the class declarations are inside the namespace and there is no need to use namespace names. There is a report in &quot;Jira&amp;quot;:https://bugreports.qt.nokia.com/browse/QTBUG-15459 for improving the documentation on this.
The Person class is referenced in the Q_PROPERTY declaration of the BirthdayParty class. In order for the QML code using the classes to work as expected, then the namespace name has to be included when referring to the Person class in Q_PROPERTY declarations and in associated read and write function prototypes and also in "Q_INVOKABLE":http://doc.qt.nokia.com/latest/qobject.html#Q_INVOKABLE function prototypes. In general, C++ does not have this kind of limitation; it is enough that the class declarations are inside the namespace and there is no need to use namespace names. There is a report in "Jira":https://bugreports.qt.nokia.com/browse/QTBUG-15459 for improving the documentation on this.


=== C++ implementation ===
=== C++ implementation ===
Line 21: Line 24:
In the C++ code below we ensure that the namespace MyNamespace is listed in front of the class name Person in the read and write functions for the BirthdayParty class below:
In the C++ code below we ensure that the namespace MyNamespace is listed in front of the class name Person in the read and write functions for the BirthdayParty class below:


main.cpp<br /><code><br />#include &lt;QtGui&amp;gt;<br />#include &lt;QtDeclarative&amp;gt;
main.cpp
<code>
#include <QtGui>
#include <QtDeclarative>


namespace MyNamespace {<br /> class Person : public QObject<br /> {<br /> Q_OBJECT<br /> Q_PROPERTY(QString name READ name WRITE setName)<br /> public:<br /> Person()<br /> {}
namespace MyNamespace {
class Person : public QObject
{
Q_OBJECT
Q_PROPERTY(QString name READ name WRITE setName)
public:
Person()
{}


QString name() const<br /> {<br /> return m_name;<br /> }<br /> void setName(const QString &amp; n)<br /> {<br /> m_name = n;<br /> }
QString name() const
{
return m_name;
}
void setName(const QString &amp; n)
{
m_name = n;
}


private:<br /> QString m_name;<br /> };<br />}
private:
QString m_name;
};
}


namespace PartyNamespace {<br /> class BirthdayParty : public QObject<br /> {<br /> Q_OBJECT<br /> Q_PROPERTY(MyNamespace::Person *host READ host WRITE setHost)<br /> Q_PROPERTY(QDeclarativeListProperty&amp;lt;MyNamespace::Person&amp;gt; guests READ guests)<br /> public:<br /> BirthdayParty()<br /> {}
namespace PartyNamespace {
class BirthdayParty : public QObject
{
Q_OBJECT
Q_PROPERTY(MyNamespace::Person *host READ host WRITE setHost)
Q_PROPERTY(QDeclarativeListProperty<MyNamespace::Person> guests READ guests)
public:
BirthdayParty()
{}


MyNamespace::Person *host() const<br /> {<br /> return m_host;<br /> }<br /> void setHost(MyNamespace::Person *c)<br /> {<br /> m_host = c;<br /> }
MyNamespace::Person *host() const
{
return m_host;
}
void setHost(MyNamespace::Person *c)
{
m_host = c;
}


QDeclarativeListProperty&amp;lt;MyNamespace::Person&amp;gt; guests()<br /> {<br /> return QDeclarativeListProperty&amp;lt;MyNamespace::Person&amp;gt;(this, m_guests);<br /> }
QDeclarativeListProperty<MyNamespace::Person> guests()
{
return QDeclarativeListProperty<MyNamespace::Person>(this, m_guests);
}


private:<br /> MyNamespace::Person '''m_host;<br /> QList&amp;lt;MyNamespace::Person'''&gt; m_guests;<br /> };<br />}
private:
MyNamespace::Person '''m_host;
QList<MyNamespace::Person'''> m_guests;
};
}


#include &quot;main.moc&amp;quot;
#include "main.moc"


using namespace MyNamespace;<br />using namespace PartyNamespace;
using namespace MyNamespace;
using namespace PartyNamespace;


int main(int argc, char** argv)<br />{<br /> QApplication app(argc, argv);
int main(int argc, char** argv)
{
QApplication app(argc, argv);


qmlRegisterType&amp;lt;Person&amp;gt;(&quot;People&amp;quot;, 1, 0, &quot;Person&amp;quot;);<br /> qmlRegisterType&amp;lt;BirthdayParty&amp;gt;(&quot;People&amp;quot;, 1,0, &quot;BirthdayParty&amp;quot;);
qmlRegisterType<Person>("People", 1, 0, "Person");
qmlRegisterType<BirthdayParty>("People", 1,0, "BirthdayParty");


MyNamespace::Person myObj;<br /> PartyNamespace::BirthdayParty myParty;
MyNamespace::Person myObj;
PartyNamespace::BirthdayParty myParty;


QDeclarativeView view;<br /> view.setSource(QUrl::fromLocalFile&amp;amp;#40;&quot;main.qml&amp;quot;&amp;#41;);<br /> view.resize(200,100);<br /> view.show();<br /> return app.exec&amp;amp;#40;&amp;#41;;<br />}
QDeclarativeView view;
view.setSource(QUrl::fromLocalFile("main.qml"));
view.resize(200,100);
view.show();
return app.exec();
}


</code>
</code>
Line 59: Line 114:
main.qml
main.qml


<code><br />import People 1.0<br />import QtQuick 1.0
<code>
import People 1.0
import QtQuick 1.0


Text {<br /> text: &quot;Party people: &quot; ''myPerson.name''&quot; &quot; + person1.name + &quot; &quot; + person2.name<br /> BirthdayParty {<br /> id: myParty;<br /> host: Person {<br /> id: myPerson<br /> name: &quot;Sigurd&amp;quot;
Text {
text: "Party people: " ''myPerson.name''" " + person1.name + " " + person2.name
BirthdayParty {
id: myParty;
host: Person {
id: myPerson
name: "Sigurd"


}<br /> guests: [<br /> Person { id: person1; name: &quot;Jakob&amp;quot; },<br /> Person { id: person2; name: &quot;Dani&amp;quot; }<br /> ]<br /> }<br />}
}
guests: [
Person { id: person1; name: "Jakob" },
Person { id: person2; name: "Dani" }
]
}
}


</code>
</code>

Revision as of 10:33, 25 February 2015


English Български

[toc align_right="yes" depth="2"]

How to use a C++ class declared in a namespace with Q_PROPERTY and QML

Using a C++ class declared in a namespace with QML works out of the box, in general. All you need to do is to ensure that you register the class for usage in QML with "qmlRegisterType()":http://doc.qt.nokia.com/latest/qdeclarativeengine.html#qmlRegisterType. When you need to reference the namespaced class in a "Q_PROPERTY":http://doc.qt.nokia.com/latest/qobject.html#Q_PROPERTY however, then there are some concerns that need to be taken for this to work with QML. The example below illustrate the steps that need to be taken.

A Simple Example

The example below consists of 2 classes declared in a namespace:

MyNamespace::Person
PartyNamespace::BirthdayParty

The Person class is referenced in the Q_PROPERTY declaration of the BirthdayParty class. In order for the QML code using the classes to work as expected, then the namespace name has to be included when referring to the Person class in Q_PROPERTY declarations and in associated read and write function prototypes and also in "Q_INVOKABLE":http://doc.qt.nokia.com/latest/qobject.html#Q_INVOKABLE function prototypes. In general, C++ does not have this kind of limitation; it is enough that the class declarations are inside the namespace and there is no need to use namespace names. There is a report in "Jira":https://bugreports.qt.nokia.com/browse/QTBUG-15459 for improving the documentation on this.

C++ implementation

In the C++ code below we ensure that the namespace MyNamespace is listed in front of the class name Person in the read and write functions for the BirthdayParty class below:

main.cpp

#include <QtGui>
#include <QtDeclarative>

namespace MyNamespace {
 class Person : public QObject
 {
 Q_OBJECT
 Q_PROPERTY(QString name READ name WRITE setName)
 public:
 Person()
 {}

QString name() const
 {
 return m_name;
 }
 void setName(const QString &amp; n)
 {
 m_name = n;
 }

private:
 QString m_name;
 };
}

namespace PartyNamespace {
 class BirthdayParty : public QObject
 {
 Q_OBJECT
 Q_PROPERTY(MyNamespace::Person *host READ host WRITE setHost)
 Q_PROPERTY(QDeclarativeListProperty<MyNamespace::Person> guests READ guests)
 public:
 BirthdayParty()
 {}

MyNamespace::Person *host() const
 {
 return m_host;
 }
 void setHost(MyNamespace::Person *c)
 {
 m_host = c;
 }

QDeclarativeListProperty<MyNamespace::Person> guests()
 {
 return QDeclarativeListProperty<MyNamespace::Person>(this, m_guests);
 }

private:
 MyNamespace::Person '''m_host;
 QList<MyNamespace::Person'''> m_guests;
 };
}

#include "main.moc"

using namespace MyNamespace;
using namespace PartyNamespace;

int main(int argc, char** argv)
{
 QApplication app(argc, argv);

qmlRegisterType<Person>("People", 1, 0, "Person");
 qmlRegisterType<BirthdayParty>("People", 1,0, "BirthdayParty");

MyNamespace::Person myObj;
 PartyNamespace::BirthdayParty myParty;

QDeclarativeView view;
 view.setSource(QUrl::fromLocalFile("main.qml"));
 view.resize(200,100);
 view.show();
 return app.exec();
}

If the namespace is removed from these functions, the QML code using the classes will not work as expected.

QML implementation

The example code below shows how the namespaced classes can be used in QML

main.qml

import People 1.0
import QtQuick 1.0

Text {
 text: "Party people: " ''myPerson.name''" " + person1.name + " " + person2.name
 BirthdayParty {
 id: myParty;
 host: Person {
 id: myPerson
 name: "Sigurd"

}
 guests: [
 Person { id: person1; name: "Jakob" },
 Person { id: person2; name: "Dani" }
 ]
 }
}