在QML中,我们可以自己用已经存在的组件去重新定义一个新的组件,但是那有时候还是不能满足我们的要求。想到所有QML的组件都是由C++映射过来的,所有我们当然也能够使用C++定义自己的qml组件。
结合Qt的assistant,我来分析一下如何使用C++为qml定义新的类型。
首先,我们要用C++写一个类,就是 我们想在qml中用的类,person.h代码如下所示:
class Person : public QObject { 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; };
上面的代码段中,我们使用Q_PROPETY注册了两个属性,这两个属性就像qml内置的组件中的id,width,height等属性一样。关于Q_PROPETY不是本次讨论的重点,我们只需要知道Person中有两个属性name,shoeSize就够了。
下面要实现该Person类,person.cpp代码如下:
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; }
至此,从C++的角度来说,我们的Person类已经能够工作了,那么下面我们应该把它添加到qml中去呢,一般来说,我们只要在main函数里边使用qmlRegisterType()将该类型注册到QML中去,我们就可以像使用Item一样使用这个自定义类了,在example.qml中我们可以使用该自定义组件。
example.qml如下所示:
import People 1.0 Person { name: "Bob Jones" shoeSize: 12 }
main.cpp代码如下:
#include <QCoreApplication> #include <QDeclarativeEngine> #include <QDeclarativeComponent> #include <QDebug> #include "person.h" int main(int argc, char ** argv) { QCoreApplication app(argc, argv); qmlRegisterType<Person>("People", 1,0, "Person"); QDeclarativeEngine engine; QDeclarativeComponent component(&engine, QUrl("qrc:example.qml")); Person *person = qobject_cast<Person *>(component.create()); if (person) { qWarning() << "The person's name is" << person->name(); qWarning() << "They wear a" << person->shoeSize() << "sized shoe"; } else { qWarning() << component.errors(); } return 0; }
上面的import Pepole 1.0就好像我们在qml中经常用到的import QtQuick 1.0的道理是一样的。
qmlRegisterType<Person>("People", 1,0, "Person");
其中第一个Person是C++中的类名,People就是模块名,而最后那个Person当然就是qml中要使用的组件名了,我们可以起别的名字,不过习惯上都是和C++类名一样一样的