在上一篇我们已经安装好了Qt 5.5,现在正式开始学习Qt5中全新的Qt Quick编程。Qt Quick对于大部分人来说是一个全新的概念,对这样一个全新的东西要怎样开始学习呢?在没有专业书籍(当然,《Qt 5编程入门》现在已经出版了,在这篇文章中我们假设读者没有Qt Quick编程经验),没有网络教程,需要自己开荒的情况下,我们的线索就是Qt帮助文档!
在这一篇中,我们会从Qt帮助入手,开始进入Qt Quick的世界,先讲解一些基本的概念,然后跟大家一起看一下最简单的Qt Quick项目是什么样的。让初学者先有一个大体的印象。
环境:Windows 7 + Qt 5.5.0+ Qt Creator 3.4.2
要学习Qt Quick编程,那么到底什么是Qt Quick呢?因为Qt Quick是Qt新引入的一个东东,所以要了解它,最好的方式就是查看Qt的官方文档。这里我们打开Qt Creator,然后点击进入帮助模式,在这里选择“目录”查看方式,这样可以显示出帮助文档中主要内容的目录。在这里我们选择“Qt Qucik”条码,如下图所示。
该文档讲述了什么是Qt Quick,以及Qt Quick所有相关的内容。可以看到,这里指出Qt Quick由Qt Quick模块提供,它是一个编写QML应用的标准库。Qt Quick模块提供了两种接口:使用QML语言创建应用的QML接口和使用C++语言扩展QML的C++接口。使用Qt Quick模块,设计人员和开发人员可以轻松地构建流畅的动态式QML用户界面,并且在需要的时候,可以将这些用户界面连接到任何C++后端。
说到这里,童靴们可能很想知道,那什么是QML呢?得益于Qt强大的帮助系统,所有相关的关键字都可以链接过去,我们可以点击最上面的“Qt QML”链接到其介绍页面,如下图所示。
到该页面以后,可以看到,Qt QML模块为QML语言开发应用程序和库提供了一个框架。它定义并实现了语言及其引擎架构,并且提供了一个接口,允许应用开发者以自定义类型和集成JavaScript与C++代码的方式来扩展QML语言。Qt QML模块提供了QML和C++两套接口。如下图所示。
这里介绍了Qt QML,并且提到了QML语言,我们进一步深入,看看QML语言到底是什么!点击最上面的“QML language”关键字。这时跳转到了“QML Applications”页面,这里对QML进行了定义。
QML(Qt Meta-Object Language,Qt元对象语言)是一种用于描述应用程序用户界面的声明式编程语言。它使用一些可视组件以及这些组件之间的交互来描述用户界面。QML是一种高可读性的语言,可以使组件以动态方式进行交互,并且允许组件在用户界面中很容易地实现复用和自定义。QML允许开发者和设计者以类似的方式创建高性能的、具有流畅的动画效果的、极具视觉吸引力的应用程序。QML提供了一个具有高可读性的类似JSON的声明式语法,并提供了必要的JavaScript语句和动态属性绑定的支持。QML语言和引擎框架由Qt QML模块提供。
到这里,也许大家对QML、Qt Quick有了一定的了解,也许有的读者可能对这些概念更加模糊了。这里举个可能不是很恰当的比喻,Qt Quick之于QML,正如Qt 之于 C++,QML是Qt中开发的一个新的语言,而Qt Quick是这个语言的一个组件库,其中包含了很多用QML写的可以现成使用的组件。大家暂且这样理解,对于一些内容也不要过于执拗,等后面见得多了,用的多了,慢慢就领悟了!
对于一个新的、庞杂的语言(或者说技术)要怎么学习,正如很多同学在问如何学习Qt,内容实在太多了!?其实很简单,答案是一步一步学习!这里没有开玩笑的意思,千里之行始于足下,大家都懂的道理,只是不愿付出行动而已。那有没有捷径?答案是“有”,就是从最简单的内容开始,从最标准的教程入手,以最规范的程序为例,保证一开始自己就是纯正血统,这样才不至于写出的程序乱七八糟,错误百出,浪费大量时间也找不出bug所在。
学习Qt,最标准的教程就是帮助文档,最规范的程序就是示例程序,而且如何开始学习,Qt文档中都给了入口,比如要学习QML语言,这里可以点击“First Steps with QML”链接,而要在Qt Creator中开发Qt Quick程序,可以参考“Creating Qt Quick Projects in Qt Creator”链接,如下图所示,本篇后面的内容就是按照这些文档来的。
打开Qt Creator,点击“文件→新建文件或项目”菜单项,然后选择创建“Qt QuickApplication”,如下图所示。
在项目介绍和位置界面,设置好项目名称和源码路径,注意路径中不要包含中文。如下图所示。
下面是选择Qt Quick组件集,默认是使用Qt Quick Controls 1.3组件集,Qt Quick Controls是Qt Quick通用控件模块,这个会在后面的内容里重点讲解,由于我们初学Quick,为了不迷茫于众多新名词、新概念的大海中,这里先不介绍这个。我们选择下面的“QtQuick 2.4”,它包含了基本的QML类型,2.4是现在的版本号。如下图所示。
然后是构建套件选择,这里使用默认的Qt 5.5版本即可(如果大家的电脑上安装了多个Qt版本,可能这里会显示多个选择,因为我们现在讲的是Qt 5.5,所以只选择这个即可)。如下图所示。
最后是项目管理选项,因为我们是单独的项目,也不需要版本控制,所以直接点击“完成”即可。如下图所示。
项目创建好以后,会自动在编辑模式显示main.qml文件的内容,而在左边项目文件列表中分类显示了该项目中的所有文件。如下图所示。
我们先来运行一下这个程序,看下运行效果。按下Ctrl+R快捷键,或者点击左下角的绿色三角运行图标来编译运行程序,效果如下图所示。可以看到,这是一个最简单的Hello World程序,在一个空白窗口中显示了“Hello World”字符串,当在窗口中点击鼠标时,窗口会关闭,程序退出。
看到了运行结果,现在我们来简单看下这个main.qml文件的内容,后缀.qml表明这是个QML文件,其内容如下:
// 导入语句部分
import QtQuick 2.4
import QtQuick.Window 2.2
//对象声明部分
Window {
visible: true
MainForm {
anchors.fill: parent
mouseArea.onClicked: {
Qt.quit();
}
}
}
正如这段代码所示的,一个QML文档定义了一个QML对象树,由两部分组成:一个import导入部分,一个对象声明部分。
import导入语句类似于C++中的#include,只有导入了相关模块,才能使用其中的类型和功能。这里导入了QtQuick模块,这个就是我们前面创建项目时选择的组件集,它包含了创建用户界面所需要的基本类型和功能;而QtQuick.Window模块中提供了Window类型,它可以为Qt Quick场景创建一个顶层窗口。
下面再来看对象声明部分,QML文档中的对象声明定义了要在可视场景中显示的内容。这里创建了两个对象:Window对象和其子对象MainForm。对象(object)由它们的类型(type)指定,以大写字母开头,后面跟随一对大括号,在括号中包含了对象的特性定义,比如这个对象的属性值或者其子对象。最外层的对象叫根对象,比如这里的Window,在根对象里面定义的对象,叫做根对象的子对象,比如这里MainForm就是Window的子对象。在Window中的visible是Window的属性,用来设置窗口是否显示,可以在帮助文档中查看一个类型的所有属性及用法。
再来看MainForm,它不是QtQuick模块中的类型,而是自定义的一个用户界面表单(Qt Quick UI Forms),这是Qt 5.4以后提出的一个概念,类似于Qt C++编程中的UI文件,大家看下左边文件列表里面的MainForm.ui.qml,就是这个文件,如下图所示。
我们双击这个文件,这时会自动跳转到设计模式,也就是所谓的Qt Quick设计器。如下图所示。
在设计器中可以实现所见即所得的效果,可以弱化编码操作,专心进行设计,而后在文件中通过编码实现逻辑操作,这样也可以很大程度地把设计和逻辑相分离。Qt一直致力于改进Qt Quick设计器,比如现在这个版本就极力推荐使用设计器。但是,很多特性在设计器中还是没有办法实现的,依然需要使用代码来完成,并且,现在实际工作中还不是设计人员与编码人员的完全分离,一般我们还是程序员一个人来全部搞定。所以,实际中设计器用的并不多。
可以看到设计器中设计的界面就是程序运行显示的界面,现在我们直接按下Ctrl+2快捷键,或者点击“编辑”模式,可以看到设计器中设计的界面对应的代码,如下图所示。
在最上面有一行提示“This file should only be edited in Design mode”,就是该文件只应该在设计模式中被修改,其实这里是可以直接修改代码的。这里MainForm.ui.qml文件的内容如下:
// 导入语句
import QtQuick 2.4
// 根对象是一个矩形
Rectangle {
//声明一个新的mouseArea属性,作为子对象MouseArea的id属性的属性别名
property alias mouseArea: mouseArea
// 定义矩形的宽和高
width: 360
height: 360
// MouseArea是一个不可见项目,为它覆盖的可见项目提供鼠标处理
MouseArea {
//id属性作为该对象的标识,在其他地方可以通过id来引用该对象
id: mouseArea
// 这个属性起到布局的作用,这里就是填充整个父项目
anchors.fill: parent
}
//Text是文本项目,用来显示文本内容
Text {
// 使文本项目处于父项目的中心位置
anchors.centerIn: parent
// 文本内容是“Hello World”
text: "Hello World"
}
}
这段代码定义了一个矩形项目(在代码中,从语法角度来说Rectangle是对象,但是,从界面角度来说,叫对象不合适,我们这里叫做项目,或者会叫做组件,由于名词术语的冲突,统一把界面上可视的组件叫做项目,这个后面深入讲解),然后在矩形上面遮了一个鼠标区域MouseArea,这样整个矩形都可以接受鼠标操作了,最后在矩形的中间放了一个文本项目,显示了helloworld字符串。
这里需要说明一下,在开始用“property alias”声明了一个属性mouseArea,在根对象中声明的属性可以在其他QML文档中使用,而且“property alias mouseArea: mouseArea”后面一个mouseArea表明了它是子对象MouseArea的id属性的属性别名,也就是说在其他QML文档中操作mouseArea属性,就相当于操作这里的MouseArea对象。现在再回过头来查看main.qml文件的内容:
Window {
visible: true
MainForm {
anchors.fill: parent
mouseArea.onClicked: {
Qt.quit();
}
}
}
这里的MainForm就是MainForm.ui.qml的一个实例,而在它里面调用了mouseArea属性的onClicked事件处理器,这就相当于调用了MainForm.ui.qml中的MouseArea对象的onClicked事件处理器,其中Qt.quit()表明,当在整个矩形中点击鼠标时要执行的命令就是退出程序。
到这里,主要的两个qml文件都讲解完了,很多读者应该会感觉很乱,新的名词、新的内容还是太多,不知从何处下手。没有关系,这一篇中我们只是对创建的整个项目内容进行介绍,让大家有个初步的了解,在下一篇中我们会从最简单的内容开始讲起,然后一点点进行扩展!
讲完了主要的QML文件,下面我们再来看一下项目中的其他文件。整个项目中,所有的QML文件是以资源的形式放在.qrc文件中的,大家可以猜测QML文件跟C++源文件是不同的,它们并不需要编译,而更类似于素材。下面来看一下main.cpp文件的内容:
#include
#include
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
这个文件内容很简单,主要就是在主函数中定义了一个QQmlApplicationEngine对象,并用其加载了main.qml文件。QQmlApplicationEngine类结合了QQmlEngine和QQmlComponent两个类的功能,提供了一个便捷的方式来加载一个QML文件,但这个QML文件的所有可视内容必须放在Window对象中才能最终显示出来。对于相关的内容我们这里不再深入讲解,大家现在只需要知道,以后在main.cpp文件中通过这种方式来调用QML文件即可。
然后是myquick.pro项目文件,其中就是简单指明了程序的模板、使用的模块、源文件、资源文件等,这个与C++项目类似。还有一个deployment.pri文件,它是项目文件的补充内容,其中指出了编译到不同平台的设置信息。这些内容现在我们也不需要深入了解,这里就不再展开来说了。
这一篇中我们从学习新东西(或者说新的语言、新的技术)的最自然的角度开始,引领初学者进入Qt Quick编程的大门,帮助初学者掌握学习的技巧,学习Qt的方式。这也是网络教程与书籍的不同之处,在《Qt 5编程入门》中我们是以另外一种方式讲述的,读者的喜好不同,可以选择自己感兴趣的方式学习,或者两者都学习一下!
该篇中我们全面讲解了Qt Quick项目的所有内容,虽然没有深入,但是让初学者有了一个感性的认识,这个认识会在后面的学习过程中逐渐强化,从陌生到熟悉,最后达到灵活运用。