22——Extending QML – Object and List Property Types Example
最后更新于:2022-04-01 07:21:54
本系列所有文章可以在这里查看[http://blog.csdn.net/cloud_castle/article/category/2123873](http://blog.csdn.net/cloud_castle/article/category/2123873)
接上文[Qt5官方demo解析集21——Extending QML - Adding Types Example](http://blog.csdn.net/cloud_castle/article/details/37055429)
在上一个例子中我们基于C++创建了一个自定义的QML类型,接下来,我们将该类作为另一个类的属性类型,定义了另一个birthdayparty类。这个例子与[Qt5官方demo解析集19——Chapter 5: Using List Property Types](http://blog.csdn.net/cloud_castle/article/details/36898495)是十分相似的,只不过在这个例子中只提供了对列表属性的访问能力。[](http://blog.csdn.net/cloud_castle/article/details/36898495)
项目文件如下:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-18_569cbd083f9a1.jpg)
Person的定义和声明与上一篇博文中所贴出的一致,因此我们先看看birthdayparty.h:
~~~
#ifndef BIRTHDAYPARTY_H
#define BIRTHDAYPARTY_H
#include <QObject>
#include <QQmlListProperty> // 这个类型我们在解析集19中有讨论过,它用来提供带有列表成员的属性
#include "person.h"
// ![0]
class BirthdayParty : public QObject
{
Q_OBJECT
// ![0]
// ![1]
Q_PROPERTY(Person *host READ host WRITE setHost) // host属性,指向一个Person对象
// ![1]
// ![2]
Q_PROPERTY(QQmlListProperty<Person> guests READ guests) // guests属性,指向一个Person列表
// ![2]
// ![3]
public:
BirthdayParty(QObject *parent = 0);
Person *host() const;
void setHost(Person *);
QQmlListProperty<Person> guests(); // 上面是属性的读写函数
int guestCount() const; // 下面是自定义的用来返回客人数与读取某个客人的函数
Person *guest(int) const;
private:
Person *m_host;
QList<Person *> m_guests; // 对应的需要将m_guests定义成QList<Person *>类型的成员列表
};
// ![3]
#endif // BIRTHDAYPARTY_H
~~~
birthdayparty.cpp:
~~~
#include "birthdayparty.h"
BirthdayParty::BirthdayParty(QObject *parent)
: QObject(parent), m_host(0) // 初始化参数赋值,这个0相当于NULL
{
}
// ![0]
Person *BirthdayParty::host() const
{
return m_host;
}
void BirthdayParty::setHost(Person *c)
{
m_host = c;
}
QQmlListProperty<Person> BirthdayParty::guests()
{
return QQmlListProperty<Person>(this, m_guests); // 由一个QList得到QQmlListProperty值,函数原型如下
}
int BirthdayParty::guestCount() const // 数据成员一般都为私有,要调用它的函数,我们需要提供一个公共的接口
{
return m_guests.count();
}
Person *BirthdayParty::guest(int index) const
{
return m_guests.at(index);
}
~~~
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-18_569cbd084e8e6.jpg)
example.qml:
~~~
import People 1.0 // 由于在main函数中将Person与Birthdayparty的名称空间均注册为People 1.0,导入它我们可以同时使用这两个类型
// ![0]
BirthdayParty {
host: Person { // host参数为单Person
name: "Bob Jones"
shoeSize: 12
}
guests: [ // guests参数为多Person
Person { name: "Leo Hodges" },
Person { name: "Jack Smith" },
Person { name: "Anne Brown" }
]
}
// ![0]
~~~
main.cpp:
~~~
#include <QCoreApplication>
#include <QQmlEngine>
#include <QQmlComponent>
#include <QDebug>
#include "birthdayparty.h"
#include "person.h"
int main(int argc, char ** argv)
{
QCoreApplication app(argc, argv);
//![register list]
qmlRegisterType<BirthdayParty>("People", 1,0, "BirthdayParty"); // QML类型注册
qmlRegisterType<Person>("People", 1,0, "Person");
//![register list]
QQmlEngine engine;
QQmlComponent component(&engine, QUrl("qrc:example.qml"));
BirthdayParty *party = qobject_cast<BirthdayParty *>(component.create());
if (party && party->host()) { // 由于host为"Bob Jones",该if得以进入
qWarning() << party->host()->name() << "is having a birthday!";
qWarning() << "They are inviting:";
for (int ii = 0; ii < party->guestCount(); ++ii) // 调用公共接口得到客人数
qWarning() << " " << party->guest(ii)->name(); // 逐一访问其姓名
} else {
qWarning() << component.errors();
}
return 0;
}
~~~