QML与C++程序的整合
QML是基于JSON的描述性语言(Declarative Language),QML的程序运行于虚拟机上,具有很好的移植性。QML作为 Qt Quick的重要组成部分,结合JavaScript,能够使得GUI程序的开发更加高效,效果更加华丽,开发速度更快(有人只用一天时间就做出个手机游戏,Flying Bus )。QML与JavaScript的关系十分紧密,所以利用QtQuick开发手机应用程序的首选是JavaScript。
不过,QML同样能够与传统C++的Qt程序整合,开发移动应用。比如用C++编写部分模块供QML使用,是可行的。
如果想在用用C++编写的Qt程序中使用QML,我们应该使用QtDeclarative 模块。一个简单的例子如下:
#include
#include
#include
int main(int argc, char* argv[])
{
QApplication app(argc,argv);
QDeclarativeView view;
view.setSource(QUrl("qrc:files/animation.qml"));
view.show();
return app.exec();
}
编译运行该程序可以看到animation.qml的内容,其实该程序实现了一个最小化的qmlviewer(注:在命令行中输入 qmlviewer animation.qml 可看到animation.qml的内容)
QML与C++之间的通信是通过把C++类作为新的Element类型,提供给QML使用的:
C++中的QObject及子类,对应于QML中的不可见项。
C++中的QDeclarativeItem及子类,对应于QML中的可见项(等价于QML中的Item)。
因此,可以在C++中定义新的类型,提供给QML,过程如下:
1、子类化QObject或者QDeclarativeItem
2、注册该类到QML环境
3、在QML程序中导入这个类型
4、使用这个类型(用法同标准类型)
上述步骤1与平时的Qt C++程序一样,(QDeclarativeItem可以参考QGraphicsItem的文档,不过还有它自己的特点)。
子类化QDeclarativeItem时,记得关闭ItemHasNoContent标识位,同时在用Q_PROPERTY声明属性的时候,要记得加上NOTIFY域,否则不能使用QML的属性绑定。
注册是用以下方式:
#include
#include
#include
#include "myitem"
int main(int argc, char* argv[])
{
QApplication app(argc,argv);
qmlResigerType
QDeclarativeView view;
view.setSource(QUrl("qrc:files/animation"));
view.show();
return app.exec();
}
以上注册方法,解释一下 ,1和0分别是主版本号和次版本号,My是元素的类型名, Shapes指的就是我们的模块名, 在QML文件中就是以下命令导入自定义的模块:
import QtQuick 1.0
import Shapes 1.0
子类化QDeclarativeItem/QObject时,在C++中定义信号例如ready,则在QML中就有一个对应的onReady处理方法(用QML写)
C++中定义的公有方法,对应于QML的Methods,如果公有方法有返回值,则需要用Q_INVOKABLE修饰(声明),但是不能返回常量引用类型。
若要定义列表属性,则应该使用QDeclarativeListProperty(作为一个属性)
总结:其实QML就是对C++类的一种新的访问形式,基础知识还是Qt C++的基本概念,我们甚至可以把QML看做 Qt 的图形框架 API 提供给JavaScript语言的绑定,使得JavaScript的开发人员也能够使用Qt(注:Qt已经有几十种语言的绑定了)。
目前只能用C++来为QML服务,却不能让QML为C++服务,对身为C++爱好者的我来说,有点遗憾 ^_0
Qt Quick 加入了很多实现华丽效果的功能,说不定将来会发展成为某个手机游戏开发的框架