日志
2.2 案例2 整理一下目录吧
2018-10-23 15:45
本案例对应的源代码目录:src/chapter02/ks02_02。程序运行效果见图2-11。
图2-11 案例2运行效果 使用Qt进行开发的目的之一是开发界面类应用。本节将介绍用Qt开发界面类应用的基本步骤,并介绍如何通过修改pro文件的配置使源代码目录保持整洁。 开发界面类项目的过程大概分为四步。 (1)使用Designer绘制对话框资源文件(ui)并保存。 (2)编写界面ui对应的类CDialog。 (3)将相关文件添加到pro。 (4)使用CDialog定义对象。 下面分步骤讲解。 1.使用Designer绘制对话框资源文件(ui)并保存 启动Designer,出现如图2-12所示界面,选择template\forms中的Dialog with Buttons Bottom,然后单击【创建】按钮即可完成新建窗体工作。 图2-12 Designer新建窗体 然后,为新建的窗体设置类名:请在窗体空白处单击,然后在属性框中设置对话框的objectName(见图2-13)。设置对话框类名为CDialog,并将UI文件保存为dialog.ui。请记下这两个名称,因为后面会用到。可以根据实际需要对UI文件名、对话框类名进行命名。 图2-13 CDialog属性 然后,从Designer的工具箱的【Display Widgets】选项卡中选择Label控件(类型为QLabel,见图2-14),并拖入窗体。 图2-14 文本控件 双击该Label控件,将文字修改为“This is my dialog!”,如图2-15所示。 图2-15 编辑文本控件内容 然后,单击窗体空白处选中整个窗体,再单击工具栏上的【栅格布局】按钮为窗体设置布局(见图2-16)。 图2-16 对窗体进行栅格布局 2.编写界面ui对应的类CDialog 为dialog.ui编写对应的类CDialog,目的是为对话框增加业务功能。此处的类名CDialog来自图2-13中窗体的objectName。CDialog的头文件dialog.h的代码请见代码清单2-3。 代码清单2-3
请注意代码清单2-3中标号①处:#pragma once。该代码的作用是防止编译该头文件时发生重入的情况(多次编译同一个头文件),以免出现编译错误。 在标号②处,对命名空间Ui中的类CDialog做了前置声明,这是因为标号④处要用Ui::CDialog定义指针m_pUi。使用指针和前置声明有2个好处:一是无须在头文件中包含Ui::CDialog的头文件ui_dialog.h,因为在dialog.cpp中将包含该头文件,这在中大型项目中非常重要,因为这样做可以节省很多编译时间;二是当CDialog类(不是Ui::CDialog)需要作为DLL中的类被引出时,不会导致包含dialog.h的其他项目出现编译错误(比如,找不到ui_dialog.h)。 在标号③处,CDialog类的基类是QDialog,这是因为在Designer中绘制UI文件时选择的就是QDialog。如果不清楚CDialog的基类应该选哪一个,可以在Designer的【对象查看器】中查看。如图2-17所示,第一行对象Dialog的类名QDialog就是标号③处的基类名称。 图2-17 对象查看器 在标号④处,为了使用dialog.ui中的布局,需要为类CDialog添加私有成员Ui::CDialog* m_pUi,该对象用来初始化界面。Ui::CDialog来自dialog.ui,是通过Qt的uic命令解析dialog.ui后得到的。在项目生成的临时文件ui_dialog.h中可以找到它的定义,见代码清单2-4。在代码清单2-4中,如标号①处所示,注释中明确指出:对该文件的手工修改都将在重新编译UI文件时被覆盖。在标号②、标号③处,是界面中buttonBox、label这两个控件对象的定义。在标号④处,是初始化界面接口setupUi()的实现,在该接口中完成了对界面的初始化,包括对buttonBox、label这两个控件的构建。在标号⑤处,在命名空间Ui中定义类CDialog,该类(Ui::CDialog)将被用来定义对象m_pUi,见代码清单2-3中标号④处。 代码清单2-4
下面给出CDialog的实现文件dialog.cpp,请见代码清单2-5。 代码清单2-5
代码清单2-5中,标号①处的代码包含ui_dialog.h头文件,目的是让编译器可以看到Ui::CDialog的定义。这用到了步骤1中保存界面文件时的文件名dialog.ui。Qt的uic命令将dialog.ui文件转换为UI头文件:ui_dialog.h,即前缀ui_加上文件名dailog.ui中的dialog共同拼接成ui_dialog.h。 标号②处,在类CDialog的构造函数的初始化列表中,除了用QDialog(pParent)调用基类的构造函数进行初始化之外,还构建了m_pUi对象。 标号③处,在构造函数中一定要调用m_pUi->setupUi(this),否则界面无法正常显示。因为这处调用就是对界面进行构建。如果对该接口感兴趣,可以单步调试一下这个调用,看看setupUi()内部到底执行了什么操作。 在标号④处,当CDialog析构时需要对m_pUi指向的内存进行释放,并将m_pUi赋值为NULL。 除了将CDialog作为DLL的引出类等特殊需要外,在后续章节中不再限制使用指针还是对象的方式使用Ui::CDilaog。如果使用对象的方式,则需要把dialog.h做两处修改,见代码清单2-6中的标号①处、标号②处,而且dialog.cpp中不再编写#include"ui_dialog.h"的代码。 代码清单2-6
3.将相关文件添加到pro 目前已完成的工作包括:设计界面文件dialog.ui、编写CDialog类的定义文件dialog.h和实现文件dialog.cpp。现在把这些文件添加到项目的pro文件,见代码清单2-7。 代码清单2-7
代码清单2-7中,FORMS配置项用来描述项目中用到的UI文件列表;HEADERS和SOURCES两个配置项在前面章节介绍过,只不过在本案例中使用了多个文件。因为用到了界面控件,请确保编写QT+=widgets,否则将导致程序构建失败。 4.使用CDialog定义对象 如果用类CDialog定义对象,首先需要包含CDialog的头文件(dialog.h),然后才能定义CDialog的对象并调用其接口,见代码清单2-8。 代码清单2-8
到现在为止,为项目添加界面的工作就结束了,可以构建项目了。 但是当项目构建完成后,看一下源代码目录就会发现临时文件和临时目录太多了(如图图2-18所示方框内的文件或目录),简直杂乱不堪。一般情况下,项目组会使用代码管理工具(比如SVN)管理代码,而且可以预先设置代码入库的过滤条件,因此在提交代码时临时文件或目录不会被入库。但是,当需要备份一下源代码目录并打包时,如果有这么多临时文件(有的临时文件尺寸比较大),那可太不方便了。下面介绍如何通过修改pro文件的配置来整理源代码目录。 图2-18 案例2源代码目录 整理源代码目录的方法是引入环境变量,然后通过环境变量来设置pro中的各种路径。 首先引入一个TRAINDEVHOME的环境变量,它指向项目src的上级目录。代码的目录结构如下。 TRAINDEVHOME ------bin ------obj ------src 其中bin 、obj、src都是TRAINDEVHOME的子目录。bin目录用来存放项目生成的可执行程序和动态链接库,obj是构建项目时生成的临时文件的根目录 在pro文件中使用环境变量的语法:$$(环境变量)。比如:$$(TRAINDEVHOME)。对pro的修改见代码清单2-9。 代码清单2-9
在代码清单2-9中,OBJECTS_DIR是Qt的关键字,用来表示项目生成的临时文件的存放目录。将OBJECTS_DIR设置到obj下对应本案例的子目录。 DESTDIR是Qt的关键字,用来表示目标文件存放目录,即项目最终生成的EXE或DLL的存放目录。如果是EXE,将其设置到TRAINDEVHOME的bin子目录;如果是DLL,则设置到lib子目录。 MOC_DIR、UI_DIR是Qt的关键字,用来表示Qt的moc和uic命令生成的临时文件存放目录。将它们分别设置到OBJECTS_DIR下面的moc子目录和ui子目录。 除此之外,如果使用QtCreator进行开发,还需要设置默认构建路径,否则会导致影子构建时生成的临时文件被放到源代码目录中。选择QtCreator的【工具】|【选项】菜单项,出现【选项】对话框,选择【构建和运行】标签,再选择【概要】标签,最后修改Default builddirectory(见图2-19),将其值修改为(关于该值的拼写请见本书配套资源中【Qt Creator 4.7.2的Default builddirectory设置】): %{CurrentProject:VcsTopLevelPath}/obj/%{CurrentBuild:Name}/%{JS:Util.asciify("build-%{CurrentProject:Name}-%{CurrentKit:FileSystemName}")} 图2-19 Qt Creator默认构建目录 修改pro文件并设置完Qt Creator后,再次构建项目后得到的源代码目录见图2-20。 图2-20 整理后的目录 如果使用VS2017命令行进行构建,在每次修改pro后请重新执行qmake以便更新相应的Makefile文件;如果用VS2017的IDE进行构建,则需要更新VS 2017的IDE中的项目文件(后缀为.vcxproj的文件),方法是执行qmake –tp vc,然后用VS 2017 的IDE重新加载项目文件。 本案例介绍了开发界面类应用的步骤以及通过修改pro配置来整理源代码目录的方法,现在汇总一下知识点: (1)如果项目中需要使用界面,那么在pro中请务必添加:
(2)CDialog类的头文件中,请注意CDialog基类名称的来源以及私有的指针成员变量m_pUi以及对于Ui::CDialog的前置声明,见代码清单2-10。 代码清单2-10
(3)请注意dialog.ui对应头文件ui_dialog.h的文件名的构成规则。 (4)CDialog类的构造函数中一定要调用m_pUi->setupUi(this)。 (5)要在pro中通过环境变量设置相关目录。环境变量在使用时应该用下列语法: $$(环境变量) (6)可以在pro中定义变量,变量在使用时应该用下列语法: $$变量名称 (7)另外,还介绍了Qt关于路径设置的关键字。
《Qt 5/PyQt 5实战指南》目录 |