22HelloQt.docx
《22HelloQt.docx》由会员分享,可在线阅读,更多相关《22HelloQt.docx(12页珍藏版)》请在冰豆网上搜索。
22HelloQt
2.2-Hello-Qt
CLOSEX
LoadingImage...
2.2HelloQt
本节就从最简单的Qt程序开始,自己动手用g++编译Qt代码,并链接生成可执行程序。
接着示范一个稍微复杂点的Qt程序编译过程,包含对moc工具的使用,顺便提一下Qt元对象系统。
2.2.1HelloQt
Qt本身就是用C++语言编写的,所以Qt程序的代码看起来和普通的C++代码差不了多少,这样就很容易上手,也适合自学。
C++的套路就编写一个类,使用的时候就定义该类的对象,然后调用对象的函数来完成任务。
使用Qt控件就像上一节计算矩形的对角线、面积一样简单。
最简化的Qt程序如下面helloqt.cpp代码所示(代码文件夹为D:
\QtProjects\ch02\helloqt\):
//helloqt.cpp
#include
#include
intmain(intargc,char*argv[])
{
QApplicationa(argc,argv);
QLabellabel(QLabel:
:
tr("HelloQt!
"));
label.show();
returna.exec();
}
Qt显示一个QLabel标签控件窗口就是这么简单!
其实任何一个图形控件都可以作为主界面显示,上面使用的是QLabel。
使用Qt库,当然先要包含头文件,代码里包含了QApplication和QLabel两个类的头文件,这两个头文件位于QtWidgets文件夹里。
在上面main函数里,第1句
QApplicationa(argc,argv);
是定义一个Qt应用程序对象,它的构造函数接收和main函数一样的参数,这是Qt图形界面程序的入口,就像main函数是C++程序的入口一样。
第2句
QLabellabel(QLabel:
:
tr("HelloQt!
"));
定义了一个QLabel标签控件对象,其构造函数里以一个字符串为输入参数,代码里使用了tr函数封装了字符串。
所有的Qt类里面都有tr函数(因为tr函数在所有Qt类的顶级基类QObject里定义了),但它不是全局定义的,所以上面使用了QLabel类的tr函数。
tr函数是代表可翻译字符串的意思,因为Qt不仅跨平台,也是跨国跨语种的,所以很注重多国语言的支持,只要不是特殊情况,一般都用tr函数封装字符串,以后如果做多国语言翻译就会很方便。
QLabel就是简单地显示一小段文本,提示用户文本信息,是最常用的控件之一。
第3句
label.show();
是调用标签控件对象的show函数,显示控件窗口。
第4句
returna.exec();
exec()函数会进入Qt应用程序的事件循环函数等待用户操作,如果用户点击窗口的关闭按钮,程序就会自动结束并返回一个值,默认是0。
图形程序与命令行程序一个最大的不同就是图形程序通常不会自动关闭,而是一直等待用户操作,所以图形程序与用户的交互性都很强。
一般的命令行程序跑完自己就结束了,而图形程序会等待用户点击关闭按钮(或退出菜单项)才会结束。
QApplication的exec()函数就是用来循环等待事件的,直到出现关闭或退出信号为止。
代码是非常简单的,那如何生成可执行程序呢?
接下来我们用最原始的g++命令编译生成可执行程序,讲解其生成的过程。
这里了解一下Qt程序的生成过程,以后如果遇到程序编译链接过程中的问题,就可以对照着看看哪个步骤出了问题,进而寻找解决之法。
本节最后再给出使用qmake生成Qt程序的简洁方法,这和自己用g++编译是一样的。
下面示范Windows系统里使用MinGW编译helloqt.cpp文件,首先打开开始菜单中的Qt命令行,进入代码所在文件夹:
cd/dD:
\QtProjects\ch02\helloqt
然后执行如下一句命令编译并链接生成helloqt程序:
C:
\Qt\Qt5.4.0\5.4\mingw491_32\bin文件夹里。
一般Qt程序在Windows系统里运行所依赖的动态库比较多,以后会讲Qt程序的静态链接发布方式,在讲Qt静态库之前大家不要纠结这些动态库的事,都在Qt命令行里运行程序就行了。
2.2.2HelloWidget
刚才是使用最简化的QLabel作为主界面显示,实际中当然不会只用这么简单的窗口。
接下来介绍从QWidget类派生一个窗口作为主界面,在主界面里面显示一个QLabel控件。
QWidget是Qt各种窗口和控件的基类,它本身就是一个功能丰富的窗口类,可以从它继承来构造自定义的主界面。
需要注意的是QtWidgets是Qt的一个大模块,里面有很多窗口和控件类,而QWidget就是这些类的基类,注意看清楚这两个英文词的拼写。
我们在D:
\QtProjects\ch02\hellowidget文件夹里创建三个代码文件:
hellowidget.h、hellowidget.cpp、main.cpp,按下面输入代码,首先是hellowidget.h:
//hellowidget.h
#include
#include
classHelloWidget:
publicQWidget
{
Q_OBJECT
public:
explicitHelloWidget(QWidget*parent=0);
~HelloWidget();
//label
QLabel*m_labelInfo;
};
hellowidget.h包含了两个头文件QWidget和QLabel,接着定义了一个HelloWidget类,是从窗口通用基类QWidget继承的。
类里面最特殊的就是Q_OBJECT宏,这个宏声明了Qt元对象系统必需的函数和成员变量,之后我们会用moc工具生成元对象系统的实体函数代码。
接着定义了HelloWidget构造函数,构造函数接收一个父窗口指针作为参数,0就是NULL指针。
然后是析构函数,最后一个是QLabel指针,之后会在构造函数里创建QLabel对象。
接下来看看hellowidget.cpp:
//hellowidget.cpp
#include"hellowidget.h"
HelloWidget:
:
HelloWidget(QWidget*parent):
QWidget(parent)
{
resize(300,200);
m_labelInfo=newQLabel(tr("
HelloWidget!
"),this);
m_labelInfo->setGeometry(10,10,200,40);
}
HelloWidget:
:
~HelloWidget()
{
deletem_labelInfo;m_labelInfo=NULL;
}
这源文件里只有一个构造函数和一个析构函数。
构造函数最开始的地方用parent指针初始化了父类。
构造函数内部第一句是重新设置本窗口的尺寸,设置为宽度300像素,高度200像素。
构造函数内第二句用new创建了QLabel对象,对象构造参数里tr函数包装的就是要显示的信息,这里不需要像上一个例子使用QLabel:
:
tr方式,因为窗口基类里定义好了tr函数,不需要指定用别的类里的tr函数,其实各个类里的tr函数功能都是一样的。
字符串里面
...
是HTML网页标记语言的句式,代表显示标题一类型的文字,QLabel会自动解析HTML标记,等会就可以看到效果。
QLabel构造的第二个参数是指定本窗口为QLabel对象的父窗口。
构造函数内第三句是设置QLabel显示的矩形区域,显示的矩形区域左上角坐标是距离左边框10像素,距离上边缘10像素(不计窗口标题栏),标签控件的宽度是200像素,高度是40像素。
最后的析构函数里就是删除之前new的标签控件对象,然后把指针设置为NULL。
这里看不到Qt元对象系统的实际函数代码,因为还没有生成,以后需要用moc工具生成相应代码,这个HelloWidget类的代码才会完整。
再看看main.cpp:
//main.cpp
#include
#include"hellowidget.h"
intmain(intargc,char*argv[])
{
QApplicationa(argc,argv);
HelloWidgethw;
hw.show();
returna.exec();
}
main函数还是一如既往的简单,由于使用自定义的HelloWidget作为主窗口类,所以是包含了hellowidget.h和QApplication两个头文件。
main函数里第一句定义Qt图形界面程序的入口对象a,第二句是我们自定义主界面类HelloWidget的对象hw,第三句是显示该窗口对象,show函数是在HelloWidget父类里实现的,所以之前hellowidget.cpp没有出现show函数代码。
最后一句进入图形界面事件等待循环,直至收到关闭或退出信号,再返回一个数值。
类似这样的main函数,我们在本教程以后每个Qt程序代码里都能看到,集成开发环境可以自动生成这样的main函数代码。
需要手工编写的代码就这些,接下来的任务就是如何编译生成可执行程序了。
之前提到Qt元对象系统,Qt是基于C++开发的,而C++本身并没有元对象系统。
元对象系统是Qt专门为C++做的扩展功能,用于支持非常强大的信号/槽机制、运行时类型定义、动态属性系统等,以后学到相关代码时再讲解。
这里是初学,就不用管元对象系统代码是怎么编写的了,会用moc工具生成就可以了。
下面逐步介绍编译链接本小节程序的过程。
(1)打开Qt命令行,进入代码所在文件夹:
cd/dD:
\QtProjects\ch02\hellowidget
(2)使用moc工具生成HelloWidget类的元对象系统代码文件moc_hellowidget.cpp:
mochellowidget.h-omoc_hellowidget.cpp
moc工具会搜索头文件hellowidget.h里面所有的Q_OBJECT宏,并生成相应的元对象系统实际源代码,输出保存为moc_hellowidget.cpp文件。
加上刚才手动编写的hellowidget.cpp和main.cpp,我们总共要编译三个cpp源码文件。
(3)编译三个源代码文件:
g++-cmoc_hellowidget.cpp-I"C:
\Qt\Qt5.4.0\5.4\mingw491_32\include"-omoc_hellowidget.o
g++-chellowidget.cpp-I"C:
\Qt\Qt5.4.0\5.4\mingw491_32\include"-ohellowidget.o
g++-cmain.cpp-I"C:
\Qt\Qt5.4.0\5.4\mingw491_32\include"-omain.o
这三个文件编译命令是完全类似的,g++的-c选项是将代码只编译成目标文件.o而不链接,-I选项参数是添加Qt库的头文件路径,-o选项参数是指明输出的目标文件名字。
(4)链接到Qt库,生成可执行程序:
g++moc_hellowidget.ohellowidget.omain.o-L"C:
\Qt\Qt5.4.0\5.4\mingw491_32\lib"-lQt5Core-lQt5Gui-lQt5Widgets-ohellowidget
g++会调用链接器,将moc_hellowidget.o、hellowidget.o、main.o这三个目标文件与Qt库链接生成可执行程序,-L选项参数指定了Qt链接库的路径,选项-lQt5Core、-lQt5Gui、-lQt5Widgets是指链接到Qt图形界面的三个基本库,分别对应动态库链接声明文件libQt5Core.a、libQt5Gui.a、libQt5Widgets.a,运行时会依赖动态库Qt5Core.dll、Qt5Gui.dll、Qt5Widgets.dll。
最后的-ohellowidget指定了生成的可执行程序名字,在Windows系统里扩展名默认为exe。
生成hellowidget.exe之后,就可以在Qt命令行里执行该程序,可以看到显示的效果:
上图显示的就是HTML标题一的字号,比上一个示例程序大了很多,自定义的主界面窗口尺寸300*200是不包括标题栏的,标题栏由Qt库自己处理生成,标题栏以下才是我们程序实际的放置控件的绘图区域,通常称为客户区域(ClientArea)。
除了HTML标题一的标记,Qt还支持很多其他的标记,如字体、字号、颜色之类的,感兴趣的读者可以自己试一试。
2.2.3使用qmake
本节HelloQt的例子编译命令还比较简单,而HelloWidget例子的编译链接命令已经开始多起来了,还得先用moc工具生成元对象系统代码。
这些还都是简单代码,如果项目里文件增多,自己敲命令当然复杂了。
因此Qt有自己专门的项目构建工具qmake。
qmake工具有两种工作模式,它首先根据项目文件夹的头文件、源文件、图形界面文件、资源文件等,生成标准的.pro项目文件。
然后使用第二种工作模式,qmake可以根据.pro文件自动生成Makefile文件,我们就只需要运行一下make就行了,这就让Qt程序的项目管理和构建生成变得轻松加愉快。
我们以上面HelloWidget例子示范qmake的简单使用过程。
在使用qmake之前,把上一小节生成的临时文件moc_hellowidget.cpp、*.o和*.exe都删了,保留手动编写的一个.h和两个.cpp文件就够了。
(1)打开Qt命令行,进入hellowidget文件夹:
cd/dD:
\QtProjects\ch02\hellowidget
(2)用qmake生成项目文件:
qmake-project"QT+=widgets"
qmake的选项-project就是指定第一种工作模式,它会扫描当前文件夹里的各种文件,然后生成对应的pro文件。
命令里附加的双引号字符串"QT+=widgets" 是我们针对Qt5自定义的一行文本,qmake会把它添加到pro文件里。
qmake默认会将QtCore、QtGui模块添加到项目文件里,但是从Qt4发展到Qt5后,将QtWidgets模块从QtGui里面分离出来了,新的QtWidgets模块不会自动添加,所以我们手动在命令里添加了QtWidgets模块,即在pro文件里添加一句QT+=widgets。
执行上面命令之后,在hellowidget文件夹里会出现一个自动命名的hellowidget.pro。
该pro文件具体内容等会分析,我们先生成可执行程序看看。
(3)用qmake生成Makefile:
qmake
qmake不带任何选项就是默认工作在第二种模式,它会扫描项目文件hellowidget.pro,自动生成Makefile文件。
执行这条命令后,项目文件夹里会多出来这些内容:
debug和release两个文件夹,以及Makefile、Makefile.Debug和Makefile.Release三个文件。
Makefile是总的生成脚本文件,Makefile.Debug用于生成可调试的目标程序,而Makefile.Release用于生成优化发行版的目标程序,总的脚本Makefile会根据不同的make命令生成相应的调试版或优化发行版程序。
debug文件夹是存储编译过程中的临时文件和可执行程序,这个是对于调试版程序。
release文件夹是也是类似的,但它是存储优化发行版的可执行程序。
(4)调用make工具生成可执行程序:
mingw32-make
MinGW的生成工具是mingw32-make,该命令执行之后,默认生成的是release版可执行程序,在release文件夹里。
如果想手动指定生成debug版本目标程序,可以执行命令:
mingw32-makedebug
如果手动指定生成release版本目标程序,可以执行命令:
mingw32-makerelease
如果希望同时生成debug和release两种版本程序,就执行:
mingw32-makeall
执行这些命令后,可以在debug文件夹里看到调试版的目标程序,在release文件夹里看到优化发行版的目标程序,这两个文件夹里还有生成目标程序过程中的一些中间产物,如moc_hellowidget.cpp、*.o等。
我们在使用qmake构建程序的过程中,就不需要自己使用moc工具为Qt类生成元对象系统代码了,因为qmake自动将moc工具命令放在Makefile里面,在构建程序时会自动处理,帮程序员省了许多事。
以后章节里还有uic、rcc等工具也会自动在Makefile里调用,这是qmake工具的方便之处。
(5)运行可执行程序:
还在刚才的Qt命令行里,如果要执行调试版目标程序:
debug\hellowidget
如果要执行优化发行版程序:
release\hellowidget
运行效果和之前小节的差不多,就不截图了。
对于Linux系统,文件路径的分隔符是/,并且在Linux里的生成工具就是make,比mingw32-make名字简短。
接下来我们看看hellowidget.pro文件里的内容:
######################################################################
#Automaticallygeneratedbyqmake(3.0)?
?
1720:
31:
152015
######################################################################
QT+=widgets
TEMPLATE=app
TARGET=hellowidget
INCLUDEPATH+=.
#Input
HEADERS+=hellowidget.h
SOURCES+=hellowidget.cppmain.cpp
文件里井号打头的都是注释,可以忽略掉。
文件里实际起作用的就只有六句。
第一句:
QT+=widgets
是我们在qmake命令里面指定添加的QtWidgets模块(即widgets),因为隐藏包含了QtCore(即core)和QtGui(即gui),所以不用手动添加core和gui。
第二句:
TEMPLATE=app
这代表生成的目标程序类型模板,app是可执行的应用程序,另外还可以生成静态库和动态库、插件等等。
一般大部分的模板都是app应用程序。
TARGET=hellowidget
TARGET指定目标程序的名字,在Windows系统里就是hellowidget.exe,在Linux系统里可执行程序不需要扩展名,直接就叫hellowidget。
INCLUDEPATH+=.
这句是将当前目录(.)添加到了包含路径(INCLUDEPATH)里,程序编译时除了从Qt库的包含路径,还会从当前目录里寻找头文件,比如hellowidget.h就在当前文件夹里。
至于Qt库的包含路径,qmake自己默认就会添加,不需要我们操心的。
HEADERS+=hellowidget.h
HEADERS就是指定项目里的头文件。
SOURCES+=hellowidget.cppmain.cpp
SOURCES就是指定项目里的源代码文件。
以后还会学到图形界面文件和资源文件等,本节只需要头文件和源代码文件。
可以看出pro文件的语法是很简洁明了的,认识点英文,猜都能猜到大致的意思是什么。
注意文件里语句既有“=”,也有“+=”,这两个的意义和C++语法类似:
“=”是赋值,左边的变量会被指定为右边的值,并且仅仅是右边的值;“+=”是追加的意思,因为qmake会给一些变量默认添加Qt内置的一些值(如Qt库的包含路径),这些值是必需的,不能被取代,所以要用追加模式。
pro文件可以通过qmake生成,或者手动编写pro文件也行。
qmake又可以按照pro文件的内容生成Makefile,然后使用make构建目标程序。
pro文件是非常关键的项目管理和控制项目生成的文件,集成开发环境QtCreator就是采用pro文件管理和生成项目的,以后我们会大量接触pro文件。
练习
①阅读这篇文章:
Qt4过渡至Qt5
本教程例子代码都是基于Qt5的,但网上许多Qt例子代码都是基于Qt4的,基于Qt4的例子通常都不能直接在Qt5环境编译生成,需要对项目文件和代码文件做一些修改,这篇文章详细描述了Qt4到Qt5的变化,内容很重要,一定要记牢。