本系列所有文章可以在這里查看[http://blog.csdn.net/cloud_castle/article/category/2123873](http://blog.csdn.net/cloud_castle/article/category/2123873)
接上文[Qt5官方demo解析集26——Extending QML - Grouped Properties Example](http://blog.csdn.net/cloud_castle/article/details/37501567)
該例子繼續在上一個例子的基礎上進行擴展,并向我們展示了向一個類型中添加附加屬性的方法。
原工程不變,我們再添加一個BirthdayPartyAttached類來為BirthdayParth類提供一個額外的屬性。
birthdayparth.h:
~~~
#ifndef BIRTHDAYPARTY_H
#define BIRTHDAYPARTY_H
#include <QObject>
#include <QDate>
#include <qqml.h>
#include "person.h"
class BirthdayPartyAttached : public QObject // 附加屬性類
{
Q_OBJECT
Q_PROPERTY(QDate rsvp READ rsvp WRITE setRsvp) // 聲明一個屬性rsvp(答復),類型為QDate
public:
BirthdayPartyAttached(QObject *object);
QDate rsvp() const;
void setRsvp(const QDate &);
private:
QDate m_rsvp;
};
class BirthdayParty : public QObject
{
Q_OBJECT
Q_PROPERTY(Person *host READ host WRITE setHost)
Q_PROPERTY(QQmlListProperty<Person> guests READ guests)
Q_CLASSINFO("DefaultProperty", "guests")
public:
BirthdayParty(QObject *parent = 0);
Person *host() const;
void setHost(Person *);
QQmlListProperty<Person> guests();
int guestCount() const;
Person *guest(int) const;
//! [static attached]
static BirthdayPartyAttached *qmlAttachedProperties(QObject *); // 需要定義一個靜態函數來返回這個靜態屬性的對象
//! [static attached]
private:
Person *m_host;
QList<Person *> m_guests;
};
//! [declare attached]
QML_DECLARE_TYPEINFO(BirthdayParty, QML_HAS_ATTACHED_PROPERTIES) // 利用QML_DECLARE_TYPEINFO聲明使BirthdayParty類得以支持附加屬性
//! [declare attached]
#endif // BIRTHDAYPARTY_H
~~~
birthdayparty.cpp:
~~~
#include "birthdayparty.h"
BirthdayPartyAttached::BirthdayPartyAttached(QObject *object)
: QObject(object)
{
}
QDate BirthdayPartyAttached::rsvp() const
{
return m_rsvp;
}
void BirthdayPartyAttached::setRsvp(const QDate &d)
{
m_rsvp = d;
}
BirthdayParty::BirthdayParty(QObject *parent)
: QObject(parent), m_host(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);
}
int BirthdayParty::guestCount() const
{
return m_guests.count();
}
Person *BirthdayParty::guest(int index) const
{
return m_guests.at(index);
}
BirthdayPartyAttached *BirthdayParty::qmlAttachedProperties(QObject *object) // 當QML聲明該附加屬性時調用這個函數,返回一個該附加屬性類的對象
{
return new BirthdayPartyAttached(object);
}
~~~
example.qml:
~~~
import People 1.0
import QtQuick 2.0 // For QColor
//! [begin]
BirthdayParty {
//! [begin]
//! [rsvp]
Boy {
name: "Robert Campbell"
BirthdayParty.rsvp: "2009-07-01" // 我們使用被附加的類型名 + "." + 附加屬性來使用這個附加屬性
}
//! [rsvp]
// ![1]
Boy {
name: "Leo Hodges"
shoe { size: 10; color: "black"; brand: "Reebok"; price: 59.95 }
BirthdayParty.rsvp: "2009-07-06"
}
// ![1]
host: Boy {
name: "Jack Smith"
shoe { size: 8; color: "blue"; brand: "Puma"; price: 19.95 }
}
//! [end]
}
//! [end]
~~~
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);
qmlRegisterType<BirthdayPartyAttached>(); // 同樣的非實例化注冊
qmlRegisterType<BirthdayParty>("People", 1,0, "BirthdayParty");
qmlRegisterType<ShoeDescription>();
qmlRegisterType<Person>();
qmlRegisterType<Boy>("People", 1,0, "Boy");
qmlRegisterType<Girl>("People", 1,0, "Girl");
QQmlEngine engine;
QQmlComponent component(&engine, QUrl("qrc:example.qml"));
BirthdayParty *party = qobject_cast<BirthdayParty *>(component.create());
if (party && party->host()) {
qWarning() << party->host()->name() << "is having a birthday!";
if (qobject_cast<Boy *>(party->host()))
qWarning() << "He is inviting:";
else
qWarning() << "She is inviting:";
for (int ii = 0; ii < party->guestCount(); ++ii) {
Person *guest = party->guest(ii);
//! [query rsvp]
QDate rsvpDate;
QObject *attached = qmlAttachedPropertiesObject<BirthdayParty>(guest, false); // 返回BirthdayParty的附加屬性對象
if (attached)
rsvpDate = attached->property("rsvp").toDate(); // 由于property提取到的數據時QVariant類型的,因此需要轉換成QDate
//! [query rsvp]
if (rsvpDate.isNull())
qWarning() << " " << guest->name() << "RSVP date: Hasn't RSVP'd";
else
qWarning() << " " << guest->name() << "RSVP date:" << qPrintable(rsvpDate.toString());
}
} else {
qWarning() << component.errors();
}
return 0;
}
~~~
顯示結果如下:

可以看到日期的顯示亂碼。這本身不能說是代碼的問題,因為國外的日期用單純的ASCII碼足夠表示了,但是由于QDate使用本地習慣顯示時間,那么在我們這它是會帶中文的,qPrintable將QString轉成了const char*,自然也就顯示不出來了。
那解決辦法是將qPrintable(rsvpDate.toString())直接改成rsvpDate.toString()就可以了。
最后顯示如下:

- 前言
- 1——Fortune Server/Client
- 2——Multicast Sender/Receiverz
- 3——Broadcast Sender/Receiver
- 4——Blocking Fortune Client
- 5——Threaded Fortune Server
- 5(總結)——Fortune例程的各個實現區別
- 6——Loopback Example
- 7——Analog Clock Example
- 8——Shaped Clock Example
- 9——Analog Clock Window Example
- 10——Qt Quick Particles Examples - Emitters
- 11——Qt Quick Particles Examples - Affectors
- 12——Qt Quick Particles Examples - CustomParticles
- 13——Qt Quick Particles Examples - Image Particles
- 14——Qt Quick Particles Examples - System
- 15——Chapter 1: Creating a New Type
- 16——Chapter 2: Connecting to C++ Methods and Signals
- 17——Chapter 3: Adding Property Bindings
- 18——Chapter 4: Using Custom Property Types
- 19——Chapter 5: Using List Property Types
- 20——Chapter 6: Writing an Extension Plugin
- 21——Extending QML - Adding Types Example
- 22——Extending QML - Object and List Property Types Example
- 23——Extending QML - Inheritance and Coercion Example
- 24——Extending QML - Default Property Example
- 25——Extending QML - Methods Example
- 26——Extending QML - Grouped Properties Example
- 27——Extending QML - Attached Properties Example
- 28——Extending QML - Signal Support Example
- 29——Extending QML - Property Value Source Example
- 30——Extending QML - Binding Example
- 31——StocQt
- 32——Qt Quick Examples - Threading
- 33——Qt Quick Examples - Window and Screen
- 34——Concentric Circles Example
- 35——Music Player
- 36——Wiggly Example
- 37——Vector Deformation