Qt5官方demo解析集26——Extending QML - Grouped Properties Example
来源:互联网 发布:varian软件 编辑:程序博客网 时间:2024/05/03 15:22
本系列所有文章可以在这里查看http://blog.csdn.net/cloud_castle/article/category/2123873
接上文Qt5官方demo解析集25——Extending QML - Methods Example
如果之前看过了我前面介绍粒子系统的朋友,应该对
velocity: AngleDirection {angleVariation: 360; magnitude: 80; magnitudeVariation: 40}
这样的属性设置格式屡见不鲜了,它实际是将一个AngleDirection类型作为velocity的属性值,这样我们就可以通过设置AngleDirection的属性值来达到对velocity更复杂的控制。
在这个例子中,Qt 向我们展示了一种更巧妙的做法 —— 直接使用AngleDirection的属性。
可能你之前经常会使用到font.family: "Ubuntu" 或是 font.pixelSize: 24 ,实际上这里的font 也是一个集合属性。
还是先把我们的项目文件介绍一下:
两个自定义的C++类:Person与BirthdayParty,资源文件中是我们的QML文件example.qml。
为了有一个直观的印象,我们先来看看qml的实现:
example.qml:
import People 1.0import QtQuick 2.0 // For QColor// ![0]BirthdayParty { host: Boy { name: "Bob Jones" shoe { size: 12; color: "white"; brand: "Bikey"; price: 90.0 } // QML语法基础保证冒号为一个赋值运算 } // 而这个语句保证了属性赋值在大括号内部进行 Boy { name: "Leo Hodges"//![grouped] shoe { size: 10; color: "black"; brand: "Thebok"; price: 59.95 }//![grouped] } // ![1] Boy { name: "Jack Smith" shoe { size: 8 color: "blue" brand: "Luma" price: 19.95 } } // ![1] Girl { name: "Anne Brown"//![ungrouped] shoe.size: 7 // 大括号拆开来实际就变成这几个单独的语句 shoe.color: "red" shoe.brand: "Job Macobs" shoe.price: 699.99//![ungrouped] }}// ![0]
这种赋值方法是如何实现的呢,来看C++的定义:
BirthdayParty提供了生日派对的框架,这个类没有变化。birthdayparty.h:
#ifndef BIRTHDAYPARTY_H#define BIRTHDAYPARTY_H#include <QObject>#include <QQmlListProperty>#include "person.h"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;private: Person *m_host; QList<Person *> m_guests;};
birthdayparty.cpp:
#include "birthdayparty.h"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);}
接下来,Person文件中定义了一个额外的类ShoeDescription用来为shoe属性提供描述。
person.h:
#ifndef PERSON_H#define PERSON_H#include <QObject>#include <QColor>class ShoeDescription : public QObject // 这个类的作用类似我们前面所说的AngleDirection,用这个自定义类型定义shoe属性{ Q_OBJECT Q_PROPERTY(int size READ size WRITE setSize) // 内部定义了四种属性:尺寸、颜色、品牌、价格 Q_PROPERTY(QColor color READ color WRITE setColor) Q_PROPERTY(QString brand READ brand WRITE setBrand) Q_PROPERTY(qreal price READ price WRITE setPrice)public: ShoeDescription(QObject *parent = 0); int size() const; void setSize(int); QColor color() const; void setColor(const QColor &); QString brand() const; void setBrand(const QString &); qreal price() const; void setPrice(qreal);private: int m_size; QColor m_color; QString m_brand; qreal m_price;};class Person : public QObject // Person类定义{ Q_OBJECT Q_PROPERTY(QString name READ name WRITE setName)// ![1] Q_PROPERTY(ShoeDescription *shoe READ shoe) // 将shoe属性设置为只读,否则它需要被冒号赋值// ![1]public: Person(QObject *parent = 0); QString name() const; void setName(const QString &); ShoeDescription *shoe();private: QString m_name; ShoeDescription m_shoe;};class Boy : public Person{ Q_OBJECTpublic: Boy(QObject * parent = 0);};class Girl : public Person{ Q_OBJECTpublic: Girl(QObject * parent = 0);};#endif // PERSON_H
person.cpp:
#include "person.h"ShoeDescription::ShoeDescription(QObject *parent): QObject(parent), m_size(0), m_price(0){}int ShoeDescription::size() const{ return m_size;}void ShoeDescription::setSize(int s){ m_size = s;}QColor ShoeDescription::color() const{ return m_color;}void ShoeDescription::setColor(const QColor &c){ m_color = c;}QString ShoeDescription::brand() const{ return m_brand;}void ShoeDescription::setBrand(const QString &b){ m_brand = b;}qreal ShoeDescription::price() const{ return m_price;}void ShoeDescription::setPrice(qreal p){ m_price = p;}Person::Person(QObject *parent): QObject(parent){}QString Person::name() const{ return m_name;}void Person::setName(const QString &n){ m_name = n;}ShoeDescription *Person::shoe(){ return &m_shoe;}Boy::Boy(QObject * parent): Person(parent){}Girl::Girl(QObject * parent): Person(parent){}
最后来看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"); qmlRegisterType<ShoeDescription>(); // 注册该类型,但不进行实例化,这与Person类相同 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:"; Person *bestShoe = 0; for (int ii = 0; ii < party->guestCount(); ++ii) { // 比较每个客人鞋子价格,得出谁穿着最好的鞋 Person *guest = party->guest(ii); qWarning() << " " << guest->name(); if (!bestShoe || bestShoe->shoe()->price() < guest->shoe()->price()) bestShoe = guest; } if (bestShoe) qWarning() << bestShoe->name() << "is wearing the best shoes!"; } else { qWarning() << component.errors(); } return 0;}
运行效果:
可以看到,要想实现类似
shoe { size: 12; color: "white"; brand: "Bikey"; price: 90.0 }这种“群属性”的设置方法,我们只需要设置shoe为只读就可以了,这样QML编译器就不会寻找shoe后面的冒号,进入大括号后的赋值语句,实际上是对ShoeDescription属性的赋值。
那么如果我们想要实现这种写法
shoe: ShoeDescription { size: 12; color: "white"; brand: "Bikey"; price: 90.0 }
该如何改动呢?
第一点是shoe属性的声明,它必须是可读写的:
Q_PROPERTY(ShoeDescription *shoe READ shoe WRITE setShoe)
当然还有对应的setShoe()函数的实现。
第二点是在main.cpp中QML类型的注册:
qmlRegisterType<ShoeDescription>("People", 1,0, "ShoeDescription");
这里的ShoeDescription就需要被实例化了。
这样就可以再次运行了。
- Qt5官方demo解析集26——Extending QML - Grouped Properties Example
- Qt5官方demo解析集27——Extending QML - Attached Properties Example
- Qt5官方demo解析集21——Extending QML - Adding Types Example
- Qt5官方demo解析集22——Extending QML - Object and List Property Types Example
- Qt5官方demo解析集23——Extending QML - Inheritance and Coercion Example
- Qt5官方demo解析集24——Extending QML - Default Property Example
- Qt5官方demo解析集25——Extending QML - Methods Example
- Qt5官方demo解析集28——Extending QML - Signal Support Example
- Qt5官方demo解析集29——Extending QML - Property Value Source Example
- Qt5官方demo解析集30——Extending QML - Binding Example
- Qt5官方demo解析集6——Loopback Example
- Qt5官方demo解析集36——Wiggly Example
- Qt5官方demo解析集36——Wiggly Example
- Qt5官方demo解析集36——Wiggly Example
- Qt5官方demo解析集7——Analog Clock Example
- Qt5官方demo解析集8——Shaped Clock Example
- Qt5官方demo解析集9——Analog Clock Window Example
- Qt5官方demo解析集34——Concentric Circles Example
- 谈一谈Cocos2d-x中的某些“大小”
- Ubuntu下彻底卸载重装mysql
- LDT代码提示功能
- ubuntu安装vaware
- linux常用缩写
- Qt5官方demo解析集26——Extending QML - Grouped Properties Example
- V2010 设置共享DLL或静态LIB
- 通过系统架构设计师
- 模拟赛 无线通讯网
- 15个NoSql数据库
- 解决”cannot modify header information – headers already sent by”的错误
- A. Perfect Pair
- windows phone 图片轮播
- [leetcode] Binary Tree Preorder Traversal