支持的数据类型用于QML中的任何C++数据–自定义属性,或信号和函数的参数,QML都必须支持其类型.
默认QML支持如下数据类型:
[list]
[]bool
[]unsigned int, int
[]float, double, qreal
[]QString
[]QUrl
[]QColor
[]QDate, QTime, QDateTime
[]QPoint, QPointF
[]QSize, QSizeF
[]QRect, QRectF
[]QVariant
[]QVariantList,QVariantMap
[]QObject
[*]由Q_ENUMS()声明的枚举类型
[/list]为了可以在QML创建和使用自定义C++类型,C++类必须使用qmlRegisterType()注册为QML类型,请见上面的Defining new QML elements 小节.
JavaScript数组和对象QML内建支持在QVariantList和JavaScript数组之间,QVariantMap和JavaScript对象间的转换.
例如,如下定义在QML中的函数需要两个参数,一个数组一个对象,使用标准的JavaScript语法访问数组和对象输出其中的内容.C++代码调用了这个函数,传递QVariantList 和QVariantMap参数,将自动转换为JavaScript的数组和对象:
// MyItem.qml Item { function readValues(anArray, anObject) { for (var i=0; i<anArray.length; i++) console.log(“Array item:”, anArray[i]) for (var prop in anObject) { console.log(“Object item:”, prop, “=”, anObject[prop]) } } }
[table]
[tr][td]
[/td][td][cpp] view plaincopy
[list=1]
[] // C++
[] QDeclarativeView view(QUrl::fromLocalFile(“MyItem.qml”));
[]
[] QVariantList list;
[] list << 10 << Qt::green << “bottles”;
[]
[] QVariantMap map;
[] map.insert(“language”, “QML”);
[] map.insert(“released”, QDate(2010, 9, 21));
[]
[] QMetaObject::invokeMethod(view.rootObject(), “readValues”,
[] Q_ARG(QVariant, QVariant::fromValue(list)),
[*] Q_ARG(QVariant, QVariant::fromValue(map)));
[/list]
[/td][/tr]
[/table]This produces output like:
[cpp] view plaincopy
[list=1]
[] Array item: 10
[] Array item: #00ff00
[] Array item: bottles
[] Object item: language = QML
[*] Object item: released = Tue Sep 21 2010 00:00:00 GMT+1000 (EST)
[/list]
同样,如果C++定义了QVariantList 或QVariantMap 类型的属性或函数参数,在QML访问时,可创建JavaScript的数组或对象,并自动被转换为QVariantList 或QVariantMap 传递给C++.
使用自定义枚举类型要在自定义C++组件中使用枚举,枚举类型必须使用Q_ENUMS宏注册到Qt的元对象系统.例如,如下C++类型具有一个Status枚举类型:
[cpp] view plaincopy
[list=1]
[] class ImageViewer : public QDeclarativeItem
[] {
[] Q_OBJECT
[] Q_ENUMS(Status)
[] Q_PROPERTY(Status status READ status NOTIFY statusChanged)
[] public:
[] enum Status {
[] Ready,
[] Loading,
[] Error
[] };
[]
[] Status status() const;
[] signals:
[] void statusChanged();
[] };
[/list]
假设ImageViewer类已经使用qmlRegisterType()进行注册,现在其Status枚举可用在QML中:
ImageViewer { onStatusChanged: { if (status == ImageViewer.Ready) console.log(“Image viewer is ready!”) } }要使用内置的枚举,C++类必须注册到QML中.如果C++类型不可实例化,可使用qmlRegisterUncreatableType()注册.在QML中枚举值其首字母必须大写.
更多信息见Writing QML extensions with C++ 和Extending QML Functionalities using C++.
枚举值作为信号参数C++信号可以向QML中传递一个枚举类型参数,假设枚举和信号定义在同一个类中,或枚举值定义在Qt命名空间(Qt Namespace)中.
此外,如果C++信号带有一个枚举参数,应该使用connect()函数与QML中的函数相关联,枚举类型必须使用qRegisterMetaType()注册.
对于QML信号,作为信号参数的枚举值使用int类型替代:
ImageViewer { signal someOtherSignal(int statusValue) Component.onCompleted: { someOtherSignal(ImageViewer.Loading) } }从字符串做自动类型转换为了方便,在QML中一些基本类型的值可使用格式化字符串指定,便于在QML中向C++传递简单的值.
[table]
[td][tr][td]Type[/td][td]String format[/td][td]Example[/td][/tr]
[tr][td]QColor[/td][td]颜色名称, “#RRGGBB”, “#RRGGBBAA”[/td][td]“red”, “#ff0000”, “#ff000000”[/td][/tr]
[tr][td]QDate[/td][td]“YYYY-MM-DD”[/td][td]“2010-05-31”[/td][/tr]
[tr][td]QPoint[/td][td]“x,y”[/td][td]“10,20”[/td][/tr]
[tr][td]QRect[/td][td]“x,y,宽x高”[/td][td]“50,50,100x100”[/td][/tr]
[tr][td]QSize[/td][td]“宽x高”[/td][td]“100x200”[/td][/tr]
[tr][td]QTime[/td][td]“hh:mm:ss”[/td][td]“14:22:55”[/td][/tr]
[tr][td]QUrl[/td][td]URL字符串[/td][td]“http://www.example.com”[/td][/tr]
[tr][td]QVector3D[/td][td]“x,y,z”[/td][td]“0,1,0”[/td][/tr]
[tr][td]枚举值[/td][td]枚举值名称[/td][td]“AlignRight”[/td][/tr]
[/table](更多字符串格式和类型见basic type documentation.)
这些字符串格式用于设置QML属性值和向C++函数传递参数.本文档中有很多范例进行演示;在上面的范例中,ApplicationData类有一个QColor类型的backgroundColor属性,在QML中使用字符串"red"而不是一个QColor对象进行赋值.
如果喜欢使用显式类型赋值,Qt对象提供了便利的全局函数来创建对象的值.例如Qt.rgba()创建一个基于RGBA的QColor值.这个函数返回的QColor类型的值可用于设置QColor类型的属性,或调用需要QColor类型参数的C++函数.
创建QML插件Qt Declarative模块包含一个QDeclarativeExtensionPlugin类,这个抽象类用于创建QML插件.可在QML应用程序中动态加载QML扩展类型.
更多信息见QDeclarativeExtensionPlugin 文档和How to Create Qt Plugins .
使用Qt资源系统管理资源文件Qt resource system 可将资源文件存储在二进制可执行文件中.这对创建QML/C++联合的应用程序很有帮助,可通过资源系统的URI(像其他图片和声音资源文件一样)调度访问QML文件,而不是使用相对或绝对文件系统路径.注意如果使用资源系统,当QML资源文件被修改后必须重新编译可执行应用程序,以便于更新包中的资源.
要在QML/C++应用程序中使用资源系统:
[list]
[]创建一个.qrc资源集合文件,以XML格式例举资源文件
[]在C++中,使用:/prefix或qrc调度URL加载主QML文件资源
[/list]这样做后,QML中所有已相对路径指定的文件都从资源文件中加载.使用资源系统完全对QML层透明;即QML代码可以用相对路径来访问资源文件,而不带有qrc调度.这个调度(qrc)只用于在C++中引用资源文件.
这是使用Qt资源系统的应用程序包.目录结构如下:
[cpp] view plaincopy
[list=1]
[] project
[] |- example.qrc
[] |- main.qml
[] |- images
[] |- background.png
[] |- main.cpp
[*] |- project.pro
[/list]
main.qml 和 background.png 文件作为资源文件打包.这在example.qrc资源文件中指定:
[cpp] view plaincopy
[list=1]
[]
[]
[]
[]
[] main.qml
[] images/background.png
[]
[]
[*]
[/list]
由于background.png 是一个资源文件,main.qml可在example.qrc中使用的相当路径引用它:
// main.qml import QtQuick 1.0 Image { source: “images/background.png” }要使QML文件正确的定位资源文件,main.cpp加载主QML文件–main.qml,访问资源文件需要使用qrc调度(scheme):
[cpp] view plaincopy
[list=1]
[] int main(int argc, char argv[])
[] {
[] QApplication app(argc, argv);
[]
[] QDeclarativeView view;
[] view.setSource(QUrl(“qrc:/main.qml”));
[] view.show();
[]
[] return app.exec();
[*] }
[/list]
最后在project.pro中将RESOURCES 变量设置为用来构建应用程序资源的example.qrc 文件:
[cpp] view plaincopy
[list=1]
[] QT += declarative
[]
[] SOURCES += main.cpp
[] RESOURCES += example.qrc
[/list]