27——Extending QML – Attached Properties Example

最后更新于:2022-04-01 07:22:06

本系列所有文章可以在这里查看[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; } ~~~ 显示结果如下: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-18_569cbd0898a3a.jpg) 可以看到日期的显示乱码。这本身不能说是代码的问题,因为国外的日期用单纯的ASCII码足够表示了,但是由于QDate使用本地习惯显示时间,那么在我们这它是会带中文的,qPrintable将QString转成了const char*,自然也就显示不出来了。 那解决办法是将qPrintable(rsvpDate.toString())直接改成rsvpDate.toString()就可以了。 最后显示如下: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-18_569cbd08a95d1.jpg)
';