本系列所有文章可以在这里查看http://blog.csdn.net/cloud_castle/article/category/2123873
接上文Qt5官方demo解析集22——Extending QML - Object and List Property Types Example
在上一个例子中,我们为BirthdayParty类创建了带有一个列表参数的属性guests,而这个列表参数的类型都是一致的,即Person。然而,使用QML的类型转换机制,我们可以使这个列表参数的类型变得不同。既然说到了这里,我们先来看看example.qml:
import People 1.0 // ![0] BirthdayParty { host: Boy { name: "Bob Jones" shoeSize: 12 } guests: [ // 要知道注册属性使我们需要给其一个固定的参数类型,如int,bool,甚至自定义的类型 Boy { name: "Leo Hodges" }, // 因此想要得到该代码的效果我们需要使用继承 Boy { name: "Jack Smith" }, // Boy与Girl均继承自Person,而我们仅仅将guests注册为Person就够了 Girl { name: "Anne Brown" } ] } // ![0]
#ifndef PERSON_H #define PERSON_H #include <QObject> class Person : public QObject // Person也没有改动 { Q_OBJECT Q_PROPERTY(QString name READ name WRITE setName) Q_PROPERTY(int shoeSize READ shoeSize WRITE setShoeSize) public: Person(QObject *parent = 0); QString name() const; void setName(const QString &); int shoeSize() const; void setShoeSize(int); private: QString m_name; int m_shoeSize; }; // ![0] class Boy : public Person // 创建一个Boy继承自Person { Q_OBJECT public: Boy(QObject * parent = 0); // 需要一个最基本的构造函数使得QML可以实例化这个对象 }; //! [girl class] class Girl : public Person // Girl同Boy { Q_OBJECT public: Girl(QObject * parent = 0); }; //! [girl class] // ![0] #endif // PERSON_H
#include "person.h" Person::Person(QObject *parent) : QObject(parent), m_shoeSize(0) { } QString Person::name() const { return m_name; } void Person::setName(const QString &n) { m_name = n; } int Person::shoeSize() const { return m_shoeSize; } void Person::setShoeSize(int s) { m_shoeSize = s; } // ![1] Boy::Boy(QObject * parent) // 由于该例子只是简单演示继承,因此也并未为派生类添加额外的功能 : Person(parent) { } Girl::Girl(QObject * parent) // 构造函数是必须的 : Person(parent) { } // ![1]
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<BirthdayParty>("People", 1,0, "BirthdayParty"); //![0] qmlRegisterType<Person>(); // 我们依然需要注册Person,否则Boy与Girl无法被强制转换为Person //![0] // 该函数参数为空,因为我们并不需要实例化一个Person的对象 //![register boy girl] qmlRegisterType<Boy>("People", 1,0, "Boy"); // 注册Boy和Girl qmlRegisterType<Girl>("People", 1,0, "Girl"); //![register boy 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) qWarning() << " " << party->guest(ii)->name(); } else { qWarning() << component.errors(); } return 0; }