2.3 Qt的开发步骤及实例
大体了解开发Qt程序的基本流程有助于Qt开发快速入门。下面以完成计算圆面积功能这一简单例子来介绍一下Qt开发程序的流程,其中涉及到Qt应用程序用户界面中的事件关联操作内容——信号和槽机制(Signal&Slot)。
本实例要实现的功能是:当用户输入一个圆的半径后,可以显示计算后的圆的面积值。运行效果如图2.4所示。
![](https://epubservercos.yuewen.com/2B733A/3590505703558801/epubprivate/OEBPS/Images/figure_0045_0035.jpg?sign=1739173201-zGzBNl56aAttLqxwH5mhM5K2aBg2QNLt-0-cee0b9931f412d6b7168f1be360f3d86)
图2.4 计算圆面积实例
Qt中开发应用程序既可以采用设计器Qt Designer方法,也可以采用编写代码方法。下面首先采用Qt设计器Qt Designer进行GUI应用程序开发,使读者对Qt开发程序的流程有一个初步的认识。然后再用编写代码的形式详细介绍Qt程序开发步骤。
2.3.1 设计器Qt Designer实现
用设计器Qt Designer实现计算圆面积,完成图2.4所示的功能,见代码CH201。步骤是:首先进行界面设计,然后编写相应的计算圆面积代码。
1.界面设计
步骤如下:
(1) 单击运行Qt Creator,进入欢迎界面如图2.1所示。单击“File”→“New File or Project...”,创建一个新的工程,如图2.5所示。
![](https://epubservercos.yuewen.com/2B733A/3590505703558801/epubprivate/OEBPS/Images/figure_0046_0036.jpg?sign=1739173201-O1AXcXBjBjsZmQbgnznPY06DtrtwLpPz-0-8f0c421502d42525d9fa6403255f2d49)
图2.5 创建一个新工程
(2) 因为需要建立一个Gui项目,所以选择“Qt4 Gui Application”,单击“OK”按钮,进入下一步。
此时,编程者在创建新工程时,需要创建什么样的工程就选择相应的工程选项即可。如:“Empty Qt4 Project”选项是创建一个空的工程;“Qt4 Console Application”选项是创建一个基于控制台的工程;“Qt4 Gui Application”选项是创建可以设计GUI的工程,如图2.6所示。选择“OK”按钮,进入下一步。
![](https://epubservercos.yuewen.com/2B733A/3590505703558801/epubprivate/OEBPS/Images/figure_0046_0037.jpg?sign=1739173201-MPMVfPnwpUX0A2CT9ETx9gEPzBHCdbXQ-0-05c24f4726500eba746f223ce80b8779)
图2.6 建立一个Gui项目
(3) 选择保存项目的路径以及定义自己项目的名字。注意,保存项目的路径中不能有中文字。项目命名没有大小写要求,依据个人习惯命名即可。这里将项目命名为Dialog,保存路径为D:\CH201,如图2.7所示。单击“Next”按钮进入下一步骤。
![](https://epubservercos.yuewen.com/2B733A/3590505703558801/epubprivate/OEBPS/Images/figure_0046_0038.jpg?sign=1739173201-7izdZBnTw2RDyfQ8EQasPJKqz8H7BvMR-0-0ef53d218e1fce2f9189539c7a8f75ad)
图2.7 保存项目
(4) 出现“Select required modules”界面。现在按照自己项目需要,添加一些功能模块,如图2.8所示。这里不需要这些功能,直接单击“Next”按钮进入下一步骤。
![](https://epubservercos.yuewen.com/2B733A/3590505703558801/epubprivate/OEBPS/Images/figure_0047_0039.jpg?sign=1739173201-yIX269jNgr5GehX8lk7tDgMbK83Am3Xv-0-dae9ee207cc896655592a3ba61b1647c)
图2.8 选择功能模块
(5) 根据实际需要,选择一个“Base class(基类)”。这里选择QDialog对话框类作为基类,这时“Class name”、“Header file”、“Source file”以及“Form file”都出现默认的文件名。注意,这些文件名都可以根据具体需要进行相应的修改。选中“Generate form”复选框,表示需要用自带的界面设计器来设计界面,否则需要用代码来完成界面的设计,如图2.9所示。选择完之后单击“Next”按钮进入下一步骤。
![](https://epubservercos.yuewen.com/2B733A/3590505703558801/epubprivate/OEBPS/Images/figure_0047_0040.jpg?sign=1739173201-THGopzAP09CHRLg1SBixSCNNlgjxDH2i-0-93db45df54db540f53e5ce13ed62276c)
图2.9 选择基类
(6) 单击“Finish”按钮完成创建,则相应的文件自动加载到文件列表中,如图2.10所示。
![](https://epubservercos.yuewen.com/2B733A/3590505703558801/epubprivate/OEBPS/Images/figure_0048_0041.jpg?sign=1739173201-K1qcQK09HXr33HuKU2c4H7RWNTKywANA-0-366aad5d9ee2678148c045a781f4e779)
图2.10 简单文件列表
此时显示的是简单的文件列表。单击中间灰色一列工具栏中的过滤符号()后,弹出一个下拉列表,此时使两个项目都是被勾选选中状态(默认选项“Simplify tree”没选中,“ide generated files”处于选中状态),如图2.11(a)所示。
![](https://epubservercos.yuewen.com/2B733A/3590505703558801/epubprivate/OEBPS/Images/figure_0048_0043.jpg?sign=1739173201-sewatRm68UmTNrOXaMH6j6BZERQktrfu-0-cd2b95317aeb00dc328c69389c7c1cda)
图2.11 选择文件列表显示形式
若单击其中“Simplify tree”项取消选中状态,此时文件列表中的文件自动分类显示,如图2.11(b)所示。
在图2.11中,各个文件包含在文件夹中,单击文件夹前面的“”图标可以显示该文件夹下的文件,如图2.12(a)所示。当单击“
”图标时,可以隐藏该文件夹下的文件。
![](https://epubservercos.yuewen.com/2B733A/3590505703558801/epubprivate/OEBPS/Images/figure_0048_0046.jpg?sign=1739173201-Ho1tTrjkVwbTJD0P9oPxaSfKhoBrROkU-0-30ece33f7fd23879ccdb615e38c93993)
图2.12 展开文件列表
若单击“Hide generated files”选项取消其选中状态,此时在文件列表中显示自动生成dialog.ui的头文件ui_dialog.h,如图2.12(b)所示。注意,在dialog.ui内添加控件并保存后才自动生成头文件ui_dialog.h。
(7) 双击dialog.ui,进入界面设计器Qt Designer编辑状态开始进行设计器(Qt Designer)编程。
拖动控件容器栏的滑动条,在最后Display Widgets容器栏(如图2.13所示)中找到Label标签控件,拖动3个此控件到中间的编辑框中;同样,在Input Widgets容器栏(如图2.14所示)中找到LineEdit标签控件,拖动1个此控件到中间的编辑框中,用来输入半径值;在Buttons容器栏(如图2.15所示)中找到Push Button标签控件,拖动1个此控件到中间的编辑框中,用来提交响应单击事件。调整各控件的位置,最后的初步布局如图2.16所示。单击编辑框的空白处使编辑框处于被选中状态,拖动右下角的小方框,调整整个框架的大小,直至调整到适当大小为止,如图2.17所示。
![](https://epubservercos.yuewen.com/2B733A/3590505703558801/epubprivate/OEBPS/Images/figure_0049_0047.jpg?sign=1739173201-P9pCQfod8k0MSlfL58z1Tmj8gUepmICu-0-95feda7602e02964520eb417408c6ecf)
图2.13 Display Widgets容器栏
![](https://epubservercos.yuewen.com/2B733A/3590505703558801/epubprivate/OEBPS/Images/figure_0049_0048.jpg?sign=1739173201-2PD4rqU193YFCf6Bnhknmq7hD18XK56r-0-dcfb4f7631780b3414cabe62d5b4c4e8)
图2.14 Input Widgets容器栏
![](https://epubservercos.yuewen.com/2B733A/3590505703558801/epubprivate/OEBPS/Images/figure_0049_0049.jpg?sign=1739173201-c9PezTako4fYY5rcYetAcS9RYA8u6J5x-0-abaa57633d333d004a83bafa8ce0a452)
图2.15 Buttons容器栏
![](https://epubservercos.yuewen.com/2B733A/3590505703558801/epubprivate/OEBPS/Images/figure_0049_0050.jpg?sign=1739173201-CvIBfUGY0kkx95g5OoxzAWwiVMVbcKNF-0-dfcb9566d3976be861e2a6baa6330fc0)
图2.16 初步布局
![](https://epubservercos.yuewen.com/2B733A/3590505703558801/epubprivate/OEBPS/Images/figure_0049_0051.jpg?sign=1739173201-IzE0iPlbklM6kNDb9PyFdwfAMFVBA1e5-0-21f465899c06167134325cec1c88f803)
图2.17 调整后的布局
下面将修改拖动到编辑框中的各控件的属性,如表2.1和图2.18所示。
![](https://epubservercos.yuewen.com/2B733A/3590505703558801/epubprivate/OEBPS/Images/figure_0049_0052.jpg?sign=1739173201-p2d5XkplmHGG9HZZgRVbYoa58R4E87z1-0-33a4640689cbc892ad7f9f217d80fc01)
图2.18 对象监视器内容
表2.1 控件的属性
![](https://epubservercos.yuewen.com/2B733A/3590505703558801/epubprivate/OEBPS/Images/figure_0049_0054.jpg?sign=1739173201-Xw5LT9PhuhVp5ZMaWGPEqONxL8eovzRc-0-b2a15fa2e1ffc387cbb8972c580f9a45)
其中,修改控件Text值的方法有两种:
● 直接双击控件本身即可修改;
● 在Qt Designer设计器中的属性栏中修改,例如修改表示半径的Label标签,如图2.19所示。
![](https://epubservercos.yuewen.com/2B733A/3590505703558801/epubprivate/OEBPS/Images/figure_0049_0053.jpg?sign=1739173201-NUOgYZoOm2e3CWR5Ijvjv580ARXLwyWo-0-414c4856f416dd3193e0c066c27ea269)
图2.19 修改半径标签objectName及Text值
最后修改areaLabel_2的“frameShape”为Panel、“frameShadow”为Sunken,如图2.20所示。最终效果如图2.21所示。
![](https://epubservercos.yuewen.com/2B733A/3590505703558801/epubprivate/OEBPS/Images/figure_0050_0055.jpg?sign=1739173201-PFW1fhzCE1wVb08SJyLb5E6P9BCsK2xv-0-ba016452dd0b2daa277bd66b4ed20671)
图2.20 修改areaLabel_2属性
![](https://epubservercos.yuewen.com/2B733A/3590505703558801/epubprivate/OEBPS/Images/figure_0050_0056.jpg?sign=1739173201-C3Hg46LV5EcZmrjKFUUghJE2gJ80wO47-0-fdf1c3e76fecce95e04ab1b40d9c26c9)
图2.21 最终效果图
下面单击左下角的运行按钮()或者使用快捷键“Ctrl+R”来运行一下程序,这时提示是否保存,单击“Save All”按钮,如图2.22所示。运行结果如图2.4所示。
![](https://epubservercos.yuewen.com/2B733A/3590505703558801/epubprivate/OEBPS/Images/figure_0050_0058.jpg?sign=1739173201-cPte1RE7uGy3Hs5jaM9HZEiUdfMaMB3U-0-1dccee5c619e0f2ca35ad7877e7a7171)
图2.22 保存界面
至此,程序的界面设计已经完成。
2.编写相应的计算圆面积代码
首先简单认识一下Qt编程环境。找到文件列表中自动添加的main.cpp文件,如图2.12(a)所示。每个工程都有一个执行的入口函数,此文件中的main()函数就是此工程的入口。下面详细介绍一下main()函数的相关内容:
#include <QtGui/QApplication> #include "dialog.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); Dialog w; w.show(); return a.exec(); }
其中:
● #include <QtGui/QApplication>:Application类的定义。在每一个使用Qt图形化应用程序中都必须使用一个QApplication对象。QApplication管理了各种各样的图形化应用程序的广泛资源、基本设置、控制流以及事件处理等。
● #include "dialog.h":包含了程序中要完成功能的Dialog类的定义,在Dialog类中封装完成所需要的功能。注意,使用哪个类时就必须将包含该类的头文件引用过来。例如,要用到一个按钮类时,则必须在此处添加一行代码:#include <QPushButton>,这表明包含了按钮(QPushButton)类的定义。以上包含的头文件还可以写成<qapplication.h>和<qpushbutton.h>的形式。
● int main(int argc, char *argv[]):是应用程序的入口,几乎在使用Qt的所有情况下, main()函数只需要在把控制转交给Qt库之前执行初始化,然后Qt库通过事件来向程序告知用户的行为。所有Qt程序中都必须有且只有一个main()函数。有两个参数argc和argv, argc是命令行变量的数量,argv是命令行变量的数组。
● QApplication a(argc, argv):a是这个程序的QApplication对象。在任何Qt的窗口系统部件被使用之前创建QApplication对象是必须的。它在这里被创建并且处理这些命令行变量。所有被Qt识别的命令行参数都会从argv中被移去(并且argc也因此而减少)。
● Dialog w:创建一个对话框对象,在该类中完成各种功能。
● w.show():当创建一个窗口部件的时候,默认它是不可见的,必须调用show()函数来使它变为可见。
● return a.exec():程序进入消息循环,等待可能输入进行响应。这里就是main()把控制权转交给Qt,Qt完成事件处理工作,当应用程序退出的时候exec()的值就会返回。在exec()中,Qt接受并处理用户和系统的事件并且把它们传递给适当的窗口部件。
现在,有两种方式可以完成计算圆面积功能:一种是通过触发按钮事件完成(方式1),另一种是通过触发输入编辑框事件完成(方式2)。
方式1:在LineEdit文本框内输入半径值,然后单击“计算”按钮,则在areaLabel_2中显示对应的圆面积。编写代码步骤如下:
(1) 右击“计算”按钮,选择“Go to slot...”,如图2.23所示。在弹出的对话框中选择clicked()信号,如图2.24所示。
![](https://epubservercos.yuewen.com/2B733A/3590505703558801/epubprivate/OEBPS/Images/figure_0051_0059.jpg?sign=1739173201-magnxJcynlAhyMa5YNG6gLtsB4AbdPFz-0-9d78a66ddf3c7ed53f3699f8e70d8bf9)
图2.23 选择Go to slot...
![](https://epubservercos.yuewen.com/2B733A/3590505703558801/epubprivate/OEBPS/Images/figure_0051_0060.jpg?sign=1739173201-Na7n1nSs3W0ZzKYCKHHZwNjRyLQ7MHaL-0-8de96b6f18750291815cee516c18a4b5)
图2.24 选择QPushButton的signal
(2) 进入dialog.cpp文件中按钮单击事件的槽函数:on_countBtn_clicked()。信号与槽连接的具体说明参照后面的知识点连接部分。在此函数中添加如下代码:
void Dialog:: on_countBtn_clicked() { bool ok; QString tempStr; QString valueStr=ui->radiusLineEdit->text(); int valueInt=valueStr.toInt(&ok); double area=valueInt*valueInt*PI;//计算圆面积 ui->areaLabel_2->setText(tempStr.setNum(area)); }
(3) 在此文件开始处添加以下语句:
const static double PI=3.1416;
定义全局变量PI。
运行程序,在LineEdit内输入半径值,单击“计算”按钮后,显示圆面积,完成计算圆面积功能。
方式2:在LineEdit内输入半径值,不需要单击按钮触发单击事件,直接就在areaLabel_2中显示圆面积。编写代码步骤如下:
(1) 在“Line Edit”编辑框上单击鼠标右键,在弹出的菜单中选择“Go to slot...”菜单项,在弹出的对话框中选择“textChanged(QString)”信号,如图2.25所示。
![](https://epubservercos.yuewen.com/2B733A/3590505703558801/epubprivate/OEBPS/Images/figure_0052_0061.jpg?sign=1739173201-vJwh2yOGvWIsIqv7Lc3bYDjAdYs3bSye-0-ce4c440a77e3ddf92358f59356dd543c)
图2.25 选择QLineEdit的signal
(2) 单击“OK”按钮,进入dialog.cpp文件中的文本编辑框,改变值内容事件的槽函数:on_radiusLineEdit_textChanged(QString )。在此函数中添加如下代码:
void Dialog::on_radiusLineEdit_textChanged(QString ) { bool ok; QString tempStr; QString valueStr=ui->radiusLineEdit->text(); int valueInt=valueStr.toInt(&ok); double area=valueInt*valueInt*PI;//计算圆面积 ui->areaLabel_2->setText(tempStr.setNum(area)); }
运行此程序,在Line Edit中输入半径值后,直接在areaLabel_2中显示圆的面积值,完成计算圆面积的功能。
2.3.2 编写代码实现
下面用编写代码的方法来实现计算圆面积的功能,见代码CH202。具体步骤如下:
(1) 首先创建一个新工程。创建过程和2.3.1中的第(1)步骤~第(6)步骤相同,只是在第(3)步骤中,项目命名为Dialog且保存路径为D:\CH202,在第(5)步骤中,取消“Generate form”的选中复选框状态。
(2) 在上述工程的dialog.h中添加如下加黑代码:
class Dialog : public QDialog { Q_OBJECT public: Dialog(QWidget *parent = 0); private: QLabel *label1,*label2; QLineEdit *lineEdit; QPushButton *button; };
此时要在文件最开始加入头文件:
#include <QLabel> #include <QLineEdit> #include <QPushButton>
其中: Q_OBJECT宏的作用是启动 Qt元对象系统的一些特性(比如支持信号和槽等),它必须放置到类定义的私有区。
注意:在文件中用到哪个类时,需要此文件开始部分引用包含此类的头文件。
(3) 在dialog.cpp中添加如下代码:
Dialog::Dialog(QWidget *parent) { : QDialog(parent) label1=new QLabel(this); label1->setText(tr("请输入圆的半径:")); lineEdit=new QLineEdit(this); label2=new QLabel(this); button=new QPushButton(this); button->setText(tr("显示对应圆的面积")); QGridLayout *mainLayout=new QGridLayout(this); mainLayout->addWidget(label1,0,0); mainLayout->addWidget(lineEdit,0,1); mainLayout->addWidget(label2,1,0); mainLayout->addWidget(button,1,1); //setLayout(mainLayout); }
其中:QGridLayout *mainLayout=new QGridLayout(this):用于布局管理器,将所有控件的位置固定,具体布局管理器的使用方法参照后面第4章的内容。
(4) 在此文件一开始添加头文件:
#include <QGridLayout>
此时运行程序结果如图2.26所示。
![](https://epubservercos.yuewen.com/2B733A/3590505703558801/epubprivate/OEBPS/Images/figure_0054_0063.jpg?sign=1739173201-xT6gnU6G9EMapH5Lgva3VePSY7jpJWZo-0-274573e898078d3da4d3a932406f8339)
图2.26 初步运行效果图
这时,会看到中文部分是乱码。为解决此问题在main.cpp中添加如下加黑代码:
int main(int argc, char *argv[]) { QApplication a(argc, argv); QTextCodec::setCodecForTr(QTextCodec::codecForLocale()); Dialog w; w.show(); return a.exec(); }
其中:类QTextCodec封装定义了显示文本(例如,“请输入圆的半径:”)字符集的转换功能。
添加头文件:
#include <QTextCodec>
再次运行程序,结果如图2.27所示。
![](https://epubservercos.yuewen.com/2B733A/3590505703558801/epubprivate/OEBPS/Images/figure_0054_0064.jpg?sign=1739173201-nHm7sWtcsUsWjZL7XxE9uPoFvrxeMTis-0-106768009c29a1fdd5116bddf2053da1)
图2.27 修改后运行效果图
以上代码完成了界面设计,下面同样以两种触发不同控件事件的方式来完成计算圆面积的功能。
方式1:在LineEdit文本框内输入所需圆的半径值,单击“显示对应圆的面积”后,在label2中显示相对应的圆的面积值。
(1) 打开dialog.h文件,在类构造函数声明后添加如下代码:
class Dialog : public QDialog { ... ... QPushButton *button; private slots: void showArea(); };
(2) 打开dialog.cpp文件,在构造函数中添加如下加黑代码:
Dialog::Dialog(QWidget *parent) : QDialog(parent) { ... ... mainLayout->addWidget(button,1,1); connect(button,SIGNAL(clicked()),this,SLOT(showArea())); }
(3) 最后在showArea()中实现显示圆面积功能,代码如下:
void Dialog::showArea() { bool ok; QString tempStr; QString valueStr=lineEdit->text(); int valueInt=valueStr.toInt(&ok); double area=valueInt*valueInt*PI; label2->setText(tempStr.setNum(area)); }
(4) 在此文件开始处添加全局变量:
const static double PI=3.1416;
(5) 在LineEdit中输入圆半径值,单击“pushbutton”后,在label2中显示对应的圆面积值,如图2.28所示。
![](https://epubservercos.yuewen.com/2B733A/3590505703558801/epubprivate/OEBPS/Images/figure_0055_0065.jpg?sign=1739173201-kYR3LRUTpg49N2UwXHxNiHWT9FE2MioP-0-aa8794d021942044e402f496b9886adc)
图2.28 最终运行效果图
方式2:在LineEdit文本框中输入所需圆的半径值后,不必单击按钮,直接在label2中显示圆的面积值。操作步骤和方式1相同,只是在上述第(2)步骤当中,添加的代码修改为如下加黑代码:
Dialog::Dialog(QWidget *parent) : QDialog(parent) { ... ... mainLayout->addWidget(button,1,1); connect(lineEdit,SIGNAL(textChanged(QString)),this,SLOT(showArea())); }
重新运行程序,在LineEdit文本框中输入圆半径值后,不必单击按钮,直接在label2中显示对应的圆面积值。
基本的Qt开发步骤已经介绍完毕,在以后章节的例子中就不再如此详细介绍了。