第2章 Hello World

Hello World程序就是让应用程序显示"Hello World"字符串。这是最简单的应用,但却包含了一个应用程序的基本要素,所以一般使用它来演示程序的创建过程。

2.1 第一个Qt Widgets应用

2.1.1 创建Qt Widgets应用

  1. 选择项目模板。打开"文件→新建文件或项目"菜单项(也可以直接按下Ctrl+N快捷键,或者单击欢迎模式中的New Project按钮),在选择模板页面选择Application(Qt)分类中的Qt Widgets Application项。
  2. 设置项目位置。在"项目介绍和位置"页面输入项目的名称为helloworld,然后单击创建路径右边的"浏览"按钮选择源码路径,例如这里是"E:\app\src\02\2-1"。如果选中了这里的"设为默认的项目路径",那么以后创建的项目会默认使用该目录 。(注意:项目名称和路径中都不能出现中文 。)
  3. 选择构建系统。这里使用默认的qmake即可,直接单击"下一步"按钮。qmake是Qt提供的一个编译工具,它可以生成与平台无关的.pro文件,然后利用该文件生成与平台相关的Makefile文件。
  4. 输入类信息。可以在"类信息"页面创建一个自定义类。这里设定类名为HelloDialog,基类选择QDialog,表明该类继承自QDialog类,使用这个类可以生成一个对话框界面。这时下面的头文件、源文件和界面文件都会自动生成,保持默认即可。
  5. 选择翻译文件。因为现在不需要进行界面翻译,所以直接单击"下一步"按钮。。
  6. 选择构建套件。现在只有一个Desktop Qt 6.5.0 MinGW 64-bit可用,会默认为Debug、Release等版本分别设置不同的目录。
  7. 设置项目管理。在这里可以看到这个项目的汇总信息,还可以使用版本控制系统。单击"完成"按钮完成项目创建。

2.1.2 编辑模式和设计模式介绍

2.1.2.1 编辑模式

  1. 项目创建完成后会直接进入编辑模式,界面默认被分为3个区域:
    1)项目树形视图:罗列了项目中的所有文件。
    2)打开的文档列表:查看已打开的项目文件。
    3)阅览编辑区:可以阅读和编辑代码。(如果觉得字体太小,可以使用快捷键Ctrl +"+"(即同时按下Ctrl键和+号键)来放大字体,使用Ctrl + "-"(减号)来缩小字体,或者使用Ctrl键+鼠标滚轮,使用Ctrl+0(数字)可以使字体还原到默认大小。)
  2. 每个分栏都可以通过左上角的下拉列表选择显示为其他内容,也可以添加新的分栏。

2.1.2.2 项目目录

项目目录中现在只有一个helloworld文件夹,其中包含了6个文件。

2.1.2.3 设计模式

在Qt Creator的编辑模式下双击项目树形视图中的hellodialog.ui文件,便进入了设计模式。设计模式由以下几部分构成:

  1. 主设计区:就是图中的中间部分,这里主要用来设计界面以及编辑各个部件的属性。。
  2. 部件列表窗口(Widget Box):这里分类罗列了各种常用的标准部件,可以使用鼠标将这些部件拖入主设计区中,放到主设计区中的界面上。
  3. 对象查看器(Object Inspector):这里列出了界面上所有部件的对象名称和父类,而且以树形结构显示了各个部件的所属关系。可以在这里单击对象来选中该部件。
  4. 属性编辑器(Property Editor):这里显示了各个部件的常用属性信息,可以在这里更改部件的一些属性,如大小、位置等。这些属性按照从祖先继承的属性、从父类继承的属性和自己的属性的顺序进行了分类。
  5. 动作(Action)编辑器与信号和槽编辑器:在这里可以对相应的对象内容进行编辑。
  6. 常用功能图标:单击最上面的侧边栏中的前4个图标可以进入相应的模式,分别是窗口部件编辑模式(这是默认模式)、信号/槽编辑模式、伙伴编辑模式和Tab顺序编辑模式。后面的几个图标用来实现添加布局管理器以及调整大小等功能。

2.1.3 项目模式和项目文件介绍

2.1.3.1 项目模式

按下快捷键Ctrl+5,或者单击"项目"图标,则可以进入项目模式。如果现在没有打开任何工程,项目模式是不可用的。项目模式分为构建和运行、编辑器、代码风格、依赖关系等多个设置页面。

1)构建配置:在构建和运行页面可以设置要构建的版本,如Debug版、Profile版和Release版本。Debug版本程序中包含了调试信息,可以用来调试,但生成的可执行文件很大;而真正发布程序时要使用Release版本,不带任何调试符号信息,并且进行了多种优化;另外Profile概述版本,带有部分调试符号信息,在Debug和Release之间取一个平衡,兼顾性能和调试,性能更优但又方便调试。

2)Shadow build选项:就是所谓的"影子构建",作用是将项目的源码和编译生成的文件分别存放,就像前面创建项目时看到的,helloworld项目经编译构建为Debug版本后会生成build-helloworld-Desktop_Qt_6_5_0_MinGW_64_bit-Debug文件夹,里面放着编译生成的所有文件。将编译输出与源代码分别存放是个很好的习惯,尤其是在使用多个Qt版本进行编译时更是如此。Shadow build选项默认是选中的,如果想让源码和编译生成的文件放在一个目录下,可以将这个选项去掉。

3)编辑器设置:在编辑器设置中可以设置默认的文件编码、制表符和缩进、鼠标和键盘的相关功能,这些都是默认的全局设置,一般不建议修改,当然也可以按照自己的习惯进行自定义设置;在代码风格设置页面可以自定义代码风格,还可以将代码风格文件导出或者导入,这里默认使用了Qt的代码风格;在依赖关系中,如果同时打开了多个项目,可以设置它们之间的依赖关系;Qt Creator集成的Clang Tools可以通过静态分析来发现C、C++和Objective-C代码中的问题,具体使用方法可以在帮助中索引Using Clang Tools关键字查看。这些选项一般都不需要更改。

2.1.3.2 项目文件

  1. 下面是建立的helloworld项目的helloworld.pro文件的内容:

    1)第1行表明了这个项目使用的模块。core模块包含了Qt的核心功能,其他所有模块都依赖于这个模块;而gui模块提供了窗口系统集成、事件处理、OpenGL和OpenGL ES集成、2D图形、基本图像、字体和文本等功能。当使用qmake工具来构建项目时,core模块和gui模块是被默认包含的,也就是说编写项目文件时不添加这两个模块也是可以编译的。其实,所谓的模块就是很多相关类的集合,可以在Qt帮助中查看Qt Core和Qt GUI关键字来查看两个模块相关内容。
    2)第3行添加了widgets模块。这行代码的意思是,如果Qt主版本大于4(也就是说当前使用的是Qt 5或者更高版本),则需要添加widgets模块。其实,直接使用"QT += widgets"也是可以的,但是为了保持与Qt 4的兼容性,建议使用这种方式。在Qt Widgets模块中提供了经典的桌面用户界面的UI元素集合,简单来说,所有C++程序用户界面部件都在该模块中。
    3)第5行开启对C++17的支持。
    4)第7~9行是注释信息,第7、8行的意思是,取消第9行的注释,那么当自己代码中使用了Qt 6中已经标记为过时的API,编译时就会出错。
    5)第11~19行分别是项目中包含的源文件、头文件和表单文件。
  2. .pro.user文件
    在项目文件夹中生成的.pro.user文件,它包含了本地构建信息,包含Qt版本和构建目录等。可以用记事本或者写字板将这个文件打开查看其内容。当使用Qt Creator打开一个.pro文件时会自动生成一个.pro.user文件。如果要打开别人的项目文件,但里面包含了user文件,Qt Creator则会弹出提示窗口,询问是否载入特定的环境设置,这时应该选择"否",然后选择自己的Qt版本即可。

2.1.4 程序的运行

  1. 使用快捷键Ctrl+R或者通过按下左下角的绿色三角运行按钮来编译运行程序。完成后,再来看一下项目目录中的文件。这里有3个Makefile文件和一个ui_hellodialog.h文件,还有两个目录debug和release等。
  2. 进入debug目录,这里有3个.o文件、一个.cpp和一个.h文件,它们是编译时生成的中间文件,可以不必管它,而剩下的一个helloworld.exe文件便是生成的可执行文件。
  3. 双击运行helloworld.exe,则会弹出系统错误对话框,提示找不到Qt6Widgets.dll文件,原因是应用程序运行是需要dll动态链接库的。可以去Qt的安装目录的bin目录下找到该文件,后面依次将其他缺少的文件复制过来即可。当提示缺少"Qt platform plugin"时,需要将插件目录中的platforms文件夹复制过来,里面只需保留qwindows.dll文件即可。
  4. 也可以直接将Qt的bin目录路径加入到系统Path环境变量 中去,这样程序运行时就可以自动找到bin目录中的dll文件了。

2.1.5 程序的发布

程序编译完成,需要进行发布,以让它在别人的计算机上也能运行。首先在Qt Creator中对helloworld程序进行Release版本的编译。在左下角的目标选择器(Target selector)中将构建目标设置为Release。

2.1.5.1 要包含的文件

编译完成之后再看工程目录中的release目录,已经生成了helloworld.exe文件。新建一个文件夹,里面包含以下文件:

1)release文件夹中的helloworld.exe。

2)Qt安装目录的bin目录中libgcc_s_seh-1.dll、libstdc+±6.dll、libwinpthread-1.dll、Qt6Core.dll、Qt6Gui.dll和Qt6Widgets.dll这6个文件。

3)Qt安装目录的plugins目录中的platforms文件夹(不要修改该文件夹名称),里面只需要保留qwindows.dll文件即可。

2.1.5.2 windeployqt工具

  1. 现在整个文件夹一共有24MB,如果使用WinRAR等打包压缩软件对它进行压缩,就只有9MB了,已经到达了可以接受的程度,这时就可以将压缩包发布出去了。
  2. Qt提供了一个windeployqt工具来自动创建可部署的文件夹。例如,生成的release版本可执行文件在C盘根目录的myapp文件夹中,则只需要在系统开始菜单的Qt目录中启动Qt 6.5.0 (MinGW 11.2.0 64-bit)命令行工具,然后输入下面命令即可:windeployqt c:\myapp。
  3. 用windeployqt工具会将所有可用的文件都复制过来,有些可能是现在并不需要的,所以建议一般情况下不要使用,只有在无法确定程序依赖的文件时再使用该工具。

2.1.6 程序源码与编译过程详解

下面将通过多种方式来实现helloworld程序,从纯代码编写,到使用.ui表单文件,再到使用自定义类,其中还会使用命令行进行代码编译。

2.1.6.1 方式一:使用纯代码编写程序

这种方式将在Qt Creator中使用纯代码编写helloworld程序并编译运行,这里的纯代码是相对于使用.ui表单文件而言的。

  1. 第一步,新建空项目。打开Qt Creator,并使用Ctrl+Shift+N快捷键新建项目,模板选择"其他项目"中的Empty qmake Project。然后将项目命名为helloworld并设置路径。完成后,双击helloworld.pro文件,添加一行代码,并保存该文件。
cpp 复制代码
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
  1. 第二步,往项目中添加main.cpp文件。在编辑模式左侧的项目树形视图中的项目目录helloworld上右击,在弹出的级联菜单中选择"添加新文件"项(也可以在编辑模式直接按下Ctrl +N快捷键),在弹出的新建文件对话框选择C/C++ Source File模板,名称设置为main.cpp,路径就是默认的项目目录。
  2. 第三步,编写源代码。向新建的main.cpp文件中添加如下代码:

    1)前3行是头文件包含。在Qt中每一个类都有一个与其同名的头文件,因为后面用到了QApplication、QDialog和QLabel这3个类,所以这里要包含这些类的定义。
    2)第4行是在C++中最常见到的main()函数,它有两个参数,用来接收命令行参数。
    3)第6行新建了QApplication类对象,用于管理应用程序的资源,任何一个Qt Widgets程序都要有一个QApplication对象。因为Qt程序可以接收命令行参数,所以它需要argc和argv两个参数。
    4)第7行新建了一个QDialog对象,QDialog类用来实现一个对话框界面。
    5)第8行新建了一个QLabel对象,并将QDialog对象作为参数,表明了对话框是它的父窗口,也就是说这个标签放在对话框窗口中。
    6)第9行给标签设置要显示的字符。
    7)第10行让对话框显示出来。在默认情况下,新建的可视部件对象都是不可见的,要使用show()函数让它们显示出来。
    8)第11行让QApplication对象进入事件循环,这样当Qt应用程序在运行时便可以接收产生的事件,例如单击和键盘按下等事件。
  3. 第四步,编译运行。再看运行的程序,发现窗口太小。
  4. 第五步,设置窗口大小。如果想改变对话框的大小,可以使用QDialog类中的函数来实现。

    在第7行代码下面另起一行,输入"w."(注:w后面输入一个"."),这时会弹出QDialog类中所有成员的列表,可以使用键盘的向下方向键↓来浏览列表,根据字面意思,这里选定了resize()函数。这时按下Enter键,代码便自动补全,并且显示出了resize()函数的原型。它有两个重载形式,用键盘方向键来查看另外的形式,这里的"int w,int h"应该就是宽和高了。
    1)第8行代码,设置对话框宽为400,高为300(单位是像素)。注意,编写代码时所有的符号都要使用输入法中的英文半角(中文字符串中的除外)。
    2)第10行代码设置了label在对话框中的位置,默认对话框的左上角是(0, 0)点。
    3)第11行添加的QObject::tr()函数可以实现多语言支持,建议程序中所有要显示到界面上的字符串都使用tr()函数括起来。

2.1.6.2 方式二:使用其他编辑器纯代码编写程序并在命令行编译运行

下面将脱离Qt Creator,使用普通文本编辑器(如Windows的记事本)编写helloworld程序,并在命令行中编译运行。

  1. 第一步,新建项目目录。在Qt的安装目录(例如:C:\Qt)中新建文件夹helloworld,然后在其中新建文本文档,并编写代码。当然也可以直接将前面main.cpp文件中的所有内容复制过来,最后将文件另存为main.cpp(保存时要将编码选择为UTF-8,否则中文可能显示乱码 )。
  2. 第二步,使用命令编译程序。打开系统开始菜单中Qt安装目录下的命令提示符程序Qt 6.5.0 (MinGW 11.2.0 64-bit),这里已经配置好了编译环境。输入命令跳转到新建的helloworld目录中:
bash 复制代码
cd C:\Qt\helloworld

然后再输入命令来生成pro工程文件:

bash 复制代码
qmake --project

这时可以看到在helloworld目录中已经生成了helloworld.pro文件。下面使用记事本打开该文件,在最后添加如下一行代码:

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

下面接着输入命令来生成用于编译的Makefile文件:

bash 复制代码
qmake

这时在helloworld目录中出现了Makefile文件和debug目录与release目录,当然这两个目录现在是空的。

接下来输入命令来编译程序:

bash 复制代码
mingw32-make

编译完成后会在release目录中出现helloworld.exe文件。

  1. 第三步,运行程序。在命令行接着输入:
bash 复制代码
cd release
helloworld.exe

按下回车键,就会运行helloworld程序了。

  1. qmake是Qt提供的一个编译工具,它可以生成与平台无关的.pro文件,然后利用该文件生成与平台相关的Makefile文件。Makefile文件中包含了要创建的目标文件或可执行文件、创建目标文件所依赖的文件和创建每个目标文件时需要运行的命令等信息。最后使用mingw32-make工具来完成自动编译,mingw32-make就是通过读入Makefile文件的内容来执行编译工作的。使用mingw32-make命令时会为每一个源文件生成一个对应的.o目标文件,最后将这些目标文件进行链接来生成最终的可执行文件。qmake.exe工具在Qt安装目录的bin目录中,而mingw32-make.exe工具在MinGW编译器目录的bin目录中,例如:C:\Qt\Tools\mingw1120_64\bin目录。

2.1.6.3 方式三:使用.ui表单文件来生成界面

.ui文件是使用设计模式生成的文件,包含了界面设计的内容。在Qt Creator中往helloworld项目里添加.ui文件,使用.ui文件生成界面来代替前面代码生成的界面。然后脱离Qt Creator,使用命令行再次编译.ui文件和整个项目。

  1. 第一步,添加.ui文件。继续添加新文件,在模板中选择Qt分类中的Qt Designer Form,在选择界面模板时选择Dialog without Buttons项。再单击"下一步",最后将文件名称改为hellodialog.ui。

  2. 第二步,设计界面。添加完文件后便进入了设计模式,在界面上拖入一个Label部件,并且更改其显示内容为"Hello World! 你好Qt!"。

然后通过右侧的属性编辑器,在其geometry属性中更改坐标位置为"X:120,Y:120",这样就与那行代码"label.move(120, 120);"起到了相同的作用。

接着在右上角的对象查看器中选择QDialog类对象,并且在下面的属性编辑器中更改它的对象名objectName为HelloDialog。

  1. 第三步,生成ui头文件。这时按下Ctrl+S快捷键保存修改,然后按下Ctrl+2快捷键回到编辑模式,那么就会看到.ui文件的内容了,它是一个XML文件,里面是界面部件的相关信息。使用Ctrl+Shift+B快捷键构建工程。然后到本地磁盘的项目目录中,就可以看到由.ui文件生成的ui_hellodialog.h头文件了。

    1)第1、2、42行是预处理指令,能够防止对这个头文件的多重包含。
    2)第3~6行包含了几个类的头文件。
    3)第8、41行是Qt的命名空间开始和结束宏。
    4)第10行定义了一个Ui_HelloDialog类。
    5)第13行是一个QLabel类对象的指针。
    6)第15行setupUi()函数用来生成界面。
    7)第17、18行设置了对话框的对象名称。
    8)第19行设置了窗口的大小。
    9)第20~22行创建了标签对象,并设置了对象名称、大小和位置。
    10)第24行调用了retranslateUi()函数,这个函数在第29~33行进行了定义,实现了对窗口里的字符串进行编码转换的功能。
    11)第26行调用了QMetaObject类的connectSlotsByName()静态函数,使得窗口中的部件可以实现按对象名进行信号和槽的关联。
    12)第37~39行定义了命名空间Ui,其中定义了一个HelloDialog类。
  2. 第四步,更改main.cpp文件。将main.cpp文件中的内容更改如下:

    1)第1行代码是头文件包含。因为在ui_hellodialog.h中已经包含了其他类的定义,所以这里只需要包含这个文件就可以了。对于头文件的包含,使用"<>"时,系统会到默认目录(编译器及环境变量、工程文件所定义的头文件寻找目录,包括Qt安装的include目录)查找要包含的文件,这是标准方式;用双引号时,系统先到用户当前目录(即项目目录)中查找要包含的文件,找不到再按标准方式查找。因为ui_hellodialog.h文件在自己的项目目录中,所以使用了双引号包含。
    2)第6行代码使用命名空间Ui中的HelloDialog类定义了一个ui对象。
    3)第7行使用了setupUi()函数,并将对话框类对象作为参数,这样就可以将设计好的界面应用到对象w所表示的对话框上了。
  3. 第五步,运行程序,则可以看到与以前相同的对话框窗口了。
  4. 在Qt Creator中完成了整个过程以后,下面来看一下怎样在命令行编译.ui文件和程序:
    1)第一步,新建项目目录。在C:\Qt目录中新建文件夹helloworld_2,然后将前面项目目录helloworld中的hellodialog.ui和main.cpp两个文件复制过来。
    2)第二步,编译.ui文件。打开命令提示符程序Qt 6.5.0 (MinGW 11.2.0 64-bit),然后输入:
bash 复制代码
cd C:\Qt\helloworld_2

进入helloworld_2目录中。再使用uic编译工具,从.ui文件生成头文件。具体命令是:

bash 复制代码
uic --o ui_hellodialog.h hellodialog.ui 

就像前面看到的那样,ui文件生成的默认头文件的名称是"ui_"加ui文件的名称。这时在helloworld_2目录中已经生成了相应的头文件。

3)第三步,编译运行程序。输入如下命令:

bash 复制代码
qmake  --project

这时在生成的helloworld_2.pro文件中添加代码"QT += widgets" ,然后依次执行如下命令:

bash 复制代码
qmake
mingw32-make
cd release
helloworld_2.exe   

这样就完成了整个编译运行过程。可以看到ui文件是使用uic编译工具来编译的,这里的Qt程序通过调用相应的头文件来使用ui界面文件。

2.1.6.4 方式四:使用自定义C++窗口类

首先新建空项目并且建立自定义的一个C++类,然后再使用前面的.ui文件。完成后可以看到设计师界面类是如何生成的。

  1. 第一步,新建空的Qt项目Empty qmake Project,项目名称为helloworld。完成后打开helloworld.pro文件,添加如下代码并保存该文件:
bash 复制代码
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
  1. 第二步,添加文件。向项目中添加新文件,模板选择C++ Class。类名Class Name设置为HelloDialog,基类Base class选择自定义,然后在下面手动填写为QDialog,其他保持默认。
  2. 第三步,编写源码。往项目中添加新的main.cpp文件。在main.cpp中添加如下代码:

    1)第2行包含了新建的HelloDialog类的头文件。
    2)第6行定义了一个该类的对象。
    这时运行程序,它会显示一个空白的对话框。
  3. 第四步,添加.ui文件。可以将前面创建的hellodialog.ui文件复制到当前项目目录下,然后在Qt Creator编辑模式左侧的项目树形视图中的项目目录helloworld上右击,在弹出的级联菜单中选择"添加现有文件"。然后在弹出的对话框中选择helloworld.ui文件,将其添加到项目中。当然,也可以不复制以前的,而是直接新建一个helloworld.ui文件。
  4. 第五步,更改C++类文件。这次不在main()函数中使用表单文件,而是在新建立的C++类中使用。先将头文件hellodialog.h修改如下:

    1)第1、2和22行是预处理指令,避免该头文件多重包含。
    2)第6~8行定义了命名空间Ui,并在其中前置声明了HelloDialog类。这个类就是在ui_hellodialog.h文件中看到的那个类。因为它与新定义的类同名,所以使用了Ui命名空间。而前置声明是为了加快编译速度,也可以避免在一个头文件中随意包含其他头文件而产生错误。因为这里只使用了该类对象的指针,如第19行定义了该类对象的指针,这并不需要该类的完整定义,所以可以使用前置声明。这样就不用在这里添加ui_hellodialog.h的头文件包含,而可以将其放到hellodialog.cpp文件中进行。
    3)第10行是新定义的HelloDialog类,继承自QDialog类。
    4)第12行使用了Q_OBJECT宏,扩展了普通C++类的功能,比如信号和槽功能,注意必须在类定义最开始的私有部分添加这个宏
    5)第15行是显式构造函数,参数是用来指定父窗口的,默认是没有父窗口。
    6)第16行是析构函数。

然后在hellodialog.cpp文件中添加代码:

1)第2行包含了ui头文件,因为hellodialog.h文件中只是使用了前置声明,所以头文件在这里添加。

2)第6行创建Ui::HelloDialog对象。

3)第7行设置setupUi()函数的参数为this,表示为现在这个类所代表的对话框创建界面。

也可以将ui的创建代码放到构造函数首部,代码如下:

这样与前面的代码效果是相同的。现在已经写出了和前面使用Qt Creator创建的helloworld项目中相同的文件和代码。此时,可以再运行程序。

2.1.6.5 方式五:使用现成的Qt设计师界面类

将方式四进行简化,因为Qt设计师界面类就是C++类和.ui文件的结合,它将这两个文件一起生成了,而不用再一个一个的添加。

  1. 再次新建空项目,名称仍为helloworld。完成后在.pro项目文件中添加如下代码并保存该文件:
bash 复制代码
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
  1. 然后向该项目中添加新文件,模板选择Qt中的"Qt设计器界面类"。界面模板依然选择Dialog without Buttons项,类名为HelloDialog。完成后在设计模式往窗口界面上添加一个Label,更改显示文本为"Hello World! 你好Qt!"。最后再往项目中添加main.cpp文件,并更改其内容如下:

2.2 第一个Qt Quick应用

如果将程序的用户界面称为前端,将程序中的数据存储和业务逻辑称为后端,那么传统Qt Widgets应用程序的前端和后端都是使用C++来完成的。对于现代软件开发而言,这里有一个存在已久的冲突:前端的演化速度要远快于后端。当用户希望在项目中改变界面,或者重新开发界面时,这种冲突就会更明显。快速演化的项目必然要求快速的开发。Qt Quick提供了一个特别适合于开发用户界面的声明式环境。在这里,可以像HTML代码一样声明界面,后端依然使用本地的C++代码。这种设计使得程序的前端和后端分为两个相互独立的部分,能够分别演化。

2.2.1 创建Qt Quick应用

2.2.1.1 使用Qt Quick Application

  1. 打开Qt Creator,选择"文件→新建项目(New Project)"菜单项(快捷键Ctrl+Shift+N),这时会弹出New Project对话框,这里先选择使用Qt Quick Application模板。
  2. 然后设置项目的名称为helloworld,并指定创建路径。在选择构建系统时,默认选择CMake。在选择最低需要的Qt版本时,默认选择最新的Qt 6.5。在构建套件选择(Kit Selection)时,因为现在只有一个桌面版构建套件Desktop Qt 6.5.0 MinGW 64-bit,所以保持默认即可。
  3. 创建完成后会自动在编辑模式打开项目,整个项目结构和Main.qml文件内容为:
  4. Qt 6.5.0版本开始,通过Qt Quick Application模板创建的项目,默认使用了CMake,而没有提供qmake的选择。CMake是一组可以进行构建、测试和打包应用程序的工具集,它可以在所有主要开发平台上使用,并且被多种IDE支持,可以很好地简化跨平台项目的构建过程。在Qt 6中,CMake得到了很大的支持。

2.2.1.2 使用Empty qmake Project

  1. 第一步,新建空项目。使用Ctrl+Shift+N快捷键新建项目,模板选择"其他项目"中的Empty qmake Project。项目名称设置为helloworld。完成后打开helloworld.pro文件,因为程序中要使用Qt Quick模块,所以需要添加如下代码并保存该文件:QT += quick。
  2. 第二步,添加main.qml文件。按下Ctrl+N向项目中添加新文件,模板选择Qt分类中的QML File(Qt Quick 2),名称设置为main.qml。完成后将其内容修改为:

    1)QML源代码文件以.qml作为扩展名,这段代码就是QML语言编写的代码。
    2)import语句用于导入相应的模块,因为下面使用的Window和Text类型包含在Qt Quick模块中,所以这里需要导入该模块。
    3)Window对象用来为Qt Quick场景创建一个新的顶层窗口,这里简单设置了其大小和标题。
    4)qsTr()是为了方便以后使用国际化机制翻译程序文本。
    5)Window默认是不显示的,可以设置visible属性让其显示。
    6)Text对象用来显示一个字符串,通过anchors属性将其锚定到窗口的中心位置。
  3. 第三步,添加main.cpp文件。继续添加新文件,选择C/C++ Source File模板,名称设置为main.cpp,完成后修改其内容如下:

    在主函数中实现的主要功能就是加载QML文件。这里使用了QQmlApplicationEngine对象来加载QML文件,这个类提供了一种简易的方式,将一个QML文件加载到正在运行的程序中。这里的当前路径为编译生成的目录,所以需要通过".../helloworld"来指定源码目录。

2.2.2 使用Qt资源文件

Qt中的资源系统(The Qt Resource System)是一个独立于平台的机制,可以将资源文件打包到应用程序可执行文件中,并且使用特定的路径来访问它们。如果在应用程序中经常使用一些文件(例如图标、翻译文件、图片等),而且不想使用系统特定的方式来打包和定位这些资源,那么就可以将它们放入资源文件中。

  1. 在前面示例源码目录中新建文件夹,命名为images,向其中放入一张图片,比如logo.png。
  2. 在编辑模式左侧的项目树形视图中最上面的helloworld目录上右击,在弹出的级联菜单中选择"添加新文件"项。
  3. 在弹出的新建文件对话框中,模板选择Qt分类下的Qt Resource File,文件名设置为resource.qrc。
  4. 完成后会在编辑模式打开新建的resource.qrc文件,这时先单击"添加前缀"按钮,这里设置为"/"即可,然后单击"添加文件"按钮将logo.png图片添加进来。最后按下Ctrl+S快捷键保存更改。
  5. 下面通过添加代码来使用资源文件中的图片,在main.qml文件的Window对象声明最后添加如下代码:
css 复制代码
import QtQuick

Window {
    ... ...    

    Image {
        id: logo
        width: 100; height: 100
        source: "qrc:/images/logo.png"
        anchors.horizontalCenter: text1.horizontalCenter
        anchors.top: text.bottom
        anchors.topMargin: 10
    }
}

1)这里的Image类型用来显示一张图片,通过source属性指定图片的路径,代码中的qrc:/images/logo.png就是资源文件中图片的路径,路径以"qrc:"开头,接着是添加的前缀"/",然后是图片文件在源码目录中的相对路径。

2)注意,添加到资源文件中的各种文件都需要与.qrc文件在同一个目录中,不然添加时会提示"无效的文件路径"。

  1. 下面在项目树形视图中resource.qrc文件上右击,在弹出的级联菜单中选择"用...打开→普通文本编辑器",这时可以看到,.qrc文件其实是一个XML文件:
xml 复制代码
<RCC>
    <qresource prefix="/">
        <file>images/logo.png</file>
    </qresource>
</RCC>
  1. 现在打开helloworld.pro项目文件,可以看到,添加资源文件会自动在这里添加代码:RESOURCES += resources.qrc。
  2. 继续向项目中添加新的QML文件,文件名设置为MyText.qml。在项目管理页面,"添加到项目"会默认选择为resource.qrc,就是直接将新文件添加到资源文件中。
  3. 添加完成后,更改其内容如下:
css 复制代码
import QtQuick

Text {
    text: qsTr("床前明月光,御姐很忧伤")
    color: "green"
}
  1. 接下来到main.qml文件中,在Window对象声明最后添加如下代码:
css 复制代码
MyText {
    anchors.top: logo.bottom
    anchors.horizontalCenter: logo.horizontalCenter
}
  1. 注意,实际编程中一般需要将所有.qml文件都放到资源文件中 。在项目树形视图中resource.qrc文件上右击,在弹出的级联菜单中选择"用...打开→资源编辑器"菜单项,然后通过"添加文件"按钮将main.qml文件添加进来,按下Ctrl+S保存修改。然后打开main.cpp文件,将加载QML文件的代码修改为:engine.load(QUrl("qrc:/main.qml"));
  2. 说明:前面新建的MyText.qml其实就是自定义了一个MyText类型,将其与main.qml放到一起,那么在main.qml文件中就可以直接使用MyText类型,而不再需要导入。

2.2.3 Qt Quick程序的发布

与前面讲到的Qt Widgets项目发布类似,要将Qt Quick程序发布出去,首先需要使用Release方式编译程序,然后将生成的.exe可执行文件和需要的库文件放在一起打包进行发布。

  1. 方式一:要确定发布时需要哪些动态库文件,可以直接双击.exe文件,提示缺少哪个dll文件,就到Qt安装目录的bin目录中将该dll文件复制过来。
  2. 方式二:使用windeployqt.exe工具。首先对helloworld程序进行Release版本的编译,然后将生成的helloworld.exe复制到要发布的文件夹中,例如D盘根目录新建的myapp文件夹,然后打开开始菜单下Qt目录中的Qt 6.5.0 (MinGW 11.2.0 64-bit)命令行工具,在其中输入下面的命令:windeployqt --qmldir E:\app\src\02\2-7\helloworld D:\myapp,对于使用了QML文件的程序,需要使用--qmldir指定项目中QML文件的路径,最后是可执行文件所在的目录路径。

2.2.4 创建Qt Quick UI项目

有些时候可能只想测试QML相关内容,希望可以快速显示界面效果,这时可以创建Qt Quick UI项目,该项目中只包含QML和JavaScript代码,没有添加任何C++代码。对于QML文件,无需编译就可以直接在预览工具中显示界面效果。

  1. 按下Ctrl+Shift+N快捷键创建新项目,模板选择"其他项目"分类中的Qt Quick UI Prototype。将项目名称设置为helloqml。
  2. 可以看到这里helloqml.qml文件内容与前面讲到的main.qml文件内容一样,但整个项目简洁了许多,除了helloqml.qml文件以外,只包含一个helloqml.qmlproject。


    1)这个helloqml.qmlproject是项目文件,其中包含了项目配置信息。可以看到,其主要指定了项目中所用的QML、JavaScript和图片等文件所在的目录(默认为当前目录)。
    2)按下Ctrl+R快捷键,程序会立即运行并显示界面,查看下面的编译输出窗口和应用程序输出窗口,可以看到,项目并没有编译,而只是启动了qml.exe工具。
    3)这就是说,单独的QML文件并不需要进行编译,就能够直接进行预览。

2.2.5 使用Qt Quick设计器

Qt Quick项目也有相应的Qt Quick Designer设计器,只是它作为插件,在现在的版本中没有默认开启。可以通过"帮助→关于插件"菜单项打开已安装的插件对话框,然后在其中勾选QmlDesigner项,完成后重启Qt Creator即可。

2.2.6 QML语法基础

  1. 导入语句(import)
    代码中的import语句导入了QtQuick模块,它包含各种QML类型。如果不使用这个import语句,下面的Rectangle和Image类型就无法使用。
css 复制代码
import QtQuick

Rectangle {
    id: root
    width: 400
    height: 400
    color: "blue"

    Image {
        source: "pics/logo.png"
        anchors.centerIn: parent
    }
}
  1. 对象(object)和属性(property)
    1)QML文档就是一个QML对象树。在这段代码中,创建了两个对象,分别是Rectangle根对象及其子对象Image。
    2)QML对象通过对象声明来定义,对象声明由对象类型(type)的名称和一对大括号组成,括号中包含了对象的特性定义,比如这个对象的id、属性值等,还可以使用嵌套对象声明的方式来声明子对象。
    3)一个对象声明一般都会在开始指定一个id,可以通过它在其他对象中识别并引用该对象,其值在一个组件的作用域中必须是唯一的。id看起来像是一个属性,但id特性并不是一个属性
    4)一般对象都会指定具体的属性值,例如矩形要设置宽、高、颜色等,这里Rectangle对象定义了width、height和color等属性。
    5)属性通过"属性:值"语法进行初始化,属性和它的值使用一个冒号隔开。属性可以分行写,此时,每行末尾的分号不是必须的。也可以将多个属性写在一行,它们之间必须使用分号分隔。
css 复制代码
import QtQuick

Rectangle {
    id: root
    width: 400
    height: 400
    color: "blue"

    Image {
        source: "pics/logo.png"
        anchors.centerIn: parent
    }
}
  1. 布局
    Image的anchors.centerIn起到了布局的作用。它会使Image处于一个对象的中心位置,比如这里就是处于其parent父对象即Rectangle的中心。除了anchors,QML还提供了很多其它布局方式。
css 复制代码
import QtQuick

Rectangle {
    id: root
    width: 400
    height: 400
    color: "blue"

    Image {
        source: "pics/logo.png"
        anchors.centerIn: parent
    }
}
  1. 注释
    QML的注释和C++是相似的:单行注释使用"//"开始,直到行末结束,多行注释使用"/"开始,以"/"结尾。
  2. 表达式和属性绑定
    1)JavaScript表达式可以用于设置属性的值,例如:
css 复制代码
Item {
    width: 100 * 3
    height: 50 + 22
}

2)在这些表达式中可以包含其它对象或属性的引用,这样做便创建了一个绑定:当表达式的值改变时,以该表达式为值的属性会自动更新为新的值。例如:Rectangle对象的width属性被设置为与它的父对象的width属性相关,只要父对象的width属性发生改变,Rectangle的width就会自动更新。

css 复制代码
Item {
    width: 300
    height: 300

    Rectangle {
        width: parent.width - 50
        height: 100
        color: "yellow"
    }
}

2.3 设置应用程序图标

  1. 第一步,创建.ico文件。可以直接在网上进行生成,完成后将.ico图标文件复制到项目目录的源码目录中,然后进行重命名,例如myico.ico。
  2. 第二步,修改项目文件。在Qt Creator中的编辑模式双击helloworld.pro文件,在最后面添加下面一行代码:RC_ICONS = myico.ico。
  3. 第三步,运行程序。可以看到窗口左上角的图标已经更换了。然后查看一下项目目录,可以看到,helloworld.exe可执行文件已经更换了新的图标。

2.4 自动补全功能

  1. 在编辑器中敲入代码时可以发现当打完开头几个字母后就会出现相关的列表选项,这些选项都是以这些字母开头的。现在要说明的是,如果要输入一个很长的字符,比如setWindowTitle,那么可以直接输入swt三个字母(就是setWindowTitle中首字母加其中的大写字母)来快速定位它,然后按下Enter按键就可以完成输入。
  2. 也可以使用Ctrl+空格键来强制代码补全,需要注意它可能与使用的输入法的快捷键冲突。
  3. 列表中各个图标都代表一种数据类型:
相关推荐
yolo_guo2 小时前
opencv 学习: QA_01 什么是图像锐化
linux·c++·opencv·计算机视觉
_OP_CHEN2 小时前
算法基础篇:(六)基础算法之双指针 —— 从暴力到高效的优化艺术
c++·算法·acm·优化算法·双指针·oj题·算法蓝桥杯
todoitbo2 小时前
Rust新手第一课:Mac环境搭建踩坑记录
开发语言·macos·rust
laplace01233 小时前
PyQt5 + Qt Designer配置指令
开发语言·qt
nvd113 小时前
Python 迭代器 (Iterator) vs. 生成器 (Generator)
开发语言·python
oioihoii3 小时前
C++中有双向映射数据结构吗?Key和Value能否双向查找?
数据结构·c++·算法
HalvmånEver3 小时前
Linux:基础开发工具(三)
linux·运维·服务器·开发语言·学习·gcc/g++
后端小张3 小时前
【JAVA 进阶】Spring Boot 注解体系与工程实践
java·开发语言·spring boot·后端·spring·spring cloud·java-ee