第3章GUI程序设计基础
本文介绍了Qt GUI项目的组成与配置方法。主要内容包括:1) Qt项目文件结构,包含.pro配置文件、UI文件和源代码文件;2) qmake构建系统的作用,解析项目配置文件中常见变量含义;3) Qt Designer可视化设计工具的功能区划分和控件属性设置;4) 主程序文件main.cpp的基本结构,说明QApplication对象初始化、窗口创建和事件循环启动过程。文章通过具体示例展示了Qt项
3.1GUI项目文件组成
在Qt Creator中创建一个新的GUI项目Test,在选择构建界面选择qmake构建系统,创建后的项目管理目录树如图3-1
3.2项目配置文件
在使用向导创建项目时,如果选择qmake构建系统,就会生成一个后缀为‘.pro’的项目配置文件,文件名称就是项目名称。文件Test.pro是本项目的配置文件,其内容如下
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++17
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
mainwindow.cpp
HEADERS += \
mainwindow.h
FORMS += \
mainwindow.ui
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
qmake是构建项目的工具软件,qmake的作用是根据项目配置文件中的设置生成Makefile文件,然后C++编译器就可以根据Makefile文件进行编译和连接。对于Qt项目,qmake还会自动为对象编译器和用户界面编译器生成构建规则。
Qt项目的配置文件是自动生成的,一般需要手动修改,但是读者需要能够读懂这些配置文件的基本意义。配置文件中“#”用于标识注释语句。配置文件中有写全大写的单词,这是qmake配置文件的变量,一些常见的变量含义如表3-1所示
表3-1qmake配置文件中常见变量的含义
| 变量 | 含义 |
|---|---|
| QT | 项目中使用Qt模块列表,在用到某些模块时需要手动添加 |
| CONFIG | 项目的通用配置 |
| DEFINES | 项目中的预处理定义列表,例如可以定义一些用于预处理的宏 |
| TEMPLATE | 项目使用的模板,项目模板可以是应用程序(app)或库(lib)。如果不设置就默认应用程序 |
| HEADERS | 项目中的头文件(.h文件)列表 |
| SOURCES | 项目中的源程序文件(.cpp文件)列表 |
| FORMS | 项目中的UI文件(.ui文件)列表 |
| RESOURCES | 项目中的资源文件(.qrc文件)列表 |
| TARGET | 项目构建后生成的应用程序的可执行文件名称,默认与项目名称相同 |
| DESTDIR | 项目可执行文件的存放路径 |
| INCLUDEPATH | 项目用到的其他头文件的搜索路径列表 |
| DEPENDPATH | 项目其他依赖文件(如源程序文件)的搜索路径列表 |
其中一些变量用于对项目中包含的文件和路径的管理,如何HEADERS、FORMS、RESOURCES、INCLUDEPATH等,当我们想项目中添加文件时,Qt Creator会自动更新配置文件的内容。在项目管理目录树种,右键点击项目节点可以调出快捷菜单,点击“添加现有文件”菜单项,可以将已有的文件添加到项目中。
变量QT可用于定义项目中用到的Qt模块。如果项目中需要用到Qt框架的一些附加模块,需要在项目配置文件中将模块加入QT变量。例如要在项目中使用Qt SQL 模块,就需要在项目配置文件中加入:
QT +=sql
qmake中提供替换函数用于在配置过程中处理变量或内置函数的值,“$$”是替换函数的前缀,后面可以是变量名或qmake的一些内置函数。如:
qnx:target.path=/tmp/$${TARGET}/bin//其中“$${TARGET}”就是替换函数,表示变量TARGET的值替换。
qnx:target.path=/tmp/$$TARGET/bin//这样也可以
3.3UI文件
后缀.ui的文件是用于窗口可视化设计的文件,如mainwindow.ui。双击它,Qt Creator会打开内置的
Qt Designer对窗口界面进行可视化设计。
Qt Designer 功能区概述
Qt Designer 是 Qt 框架中用于设计用户界面的可视化工具,其功能区包含多个核心区域,帮助用户高效完成界面设计。以下是主要功能区的介绍:
主菜单栏
位于窗口顶部,包含文件操作(新建、打开、保存)、编辑功能(撤销、重做)、视图设置(工具栏、状态栏控制)、窗口布局管理以及帮助文档入口。
工具栏
提供常用操作的快捷按钮,如保存文件、预览界面、调整控件对齐方式、切换编辑模式等。支持自定义,用户可根据需求添加或移除工具按钮。
控件工具箱
左侧面板,分类展示可拖拽的界面控件(如按钮、文本框、布局容器等)。控件按功能分组,例如“Buttons”、“Display Widgets”、“Layouts”等,支持搜索过滤。
对象查看器
通常位于右上方,以树状结构显示当前界面中的所有控件及其层级关系。支持通过拖拽调整父子关系,右键菜单可快速访问属性或信号槽编辑功能。
属性编辑器
位于对象查看器下方,列出当前选中控件的可修改属性(如尺寸、文本、样式表)。属性按类别分组,支持直接输入或通过下拉菜单选择预设值。
信号/槽编辑器
专用于连接控件信号与自定义槽函数,可视化展示事件响应逻辑。用户可通过拖拽或列表选择建立连接,支持自动生成代码框架。
资源浏览器
管理界面中使用的资源文件(如图标、图片)。支持创建资源集合(.qrc文件),方便将资源嵌入到最终应用程序中。
状态栏
窗口底部区域,显示当前操作状态、鼠标位置、缩放比例等信息。部分版本会在此处提供设计模式的快捷切换选项。
设计画布
中央区域为可视化设计界面,支持拖放控件、调整布局、实时预览。画布提供网格对齐辅助线,可通过右键菜单切换编辑模式(如控件编辑/信号槽编辑)。
提示:我们通常把处于设计阶段的UI称为窗体(from),处于运行阶段的UI称为窗口
图3-1Qt Creator中的Qt Designer工作界面
图3-2是选中窗体放置标签后属性器的显示内容。最上方显示的“label:QLabel”表示这个组件是一个QLabel类的组件,对象名称是 labe。属性编辑器内容分为两列,属性名称,属性值,属性又分为多个组,实际上表示类的继承关系,例如在图3-2中,可以看出QLabel类的继承关系是QObjec→QWidegt→QFrame→QLabel
objectName属性表示组件的对象名称,每个组件都需要一个唯一的对象名称,以便在程序中被引用。组件的命名应该遵循一定的规则,具体使用什么样的命名规则根据个人的习惯而定,主要是要便于区分和记忆,也要便于与普通变量区分。在属性编译器里可以修改组件的属性值。
| 对象名称 | 类名 | 属性设置 | 备注 |
|---|---|---|---|
| Widget | QWidget | width=200, height=100 | 基础容器控件,用于承载其他组件 |
| Label | QLabel | text=“示例文本” | 用于显示静态文本或图像 |
详细说明
Widget
- 类名: 继承自
QWidget,是Qt框架中的基础可视化组件。 - 属性设置: 通常需定义宽度(
width)和高度(height)以确定显示区域。 - 备注: 可作为其他控件的父容器,支持样式表定制。
Label
- 类名: 继承自
QLabel,专用于文本或图像展示。 - 属性设置:
text属性定义显示内容,支持富文本和动态更新。 - 备注: 可通过
setAlignment调整对齐方式,常用作界面说明性文字。
3.4主程序文件
文件main.cpp中main()函数,下面是main.cpp的完整代码
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);//定义并创建应用程序
MainWindow w;//定义并创建窗口对象
w.show();//显示窗口
return a.exec();//运行应用程序,开始应用程序的消息循环和时间处理
}
C++程序的入口点:main()函数
main()函数是C++程序的执行起点,负责初始化应用程序、创建并显示窗口,以及启动事件循环。
Qt应用程序的基本结构
在Qt应用程序中,QApplication类管理GUI控制流和主设置。
应用程序对象初始化
QApplication a(argc, argv);
QApplication对象a负责处理事件循环、系统级通信及应用程序的生命周期。
窗口创建与显示
Widget w;
w.show();
Widget是自定义窗口类,实例化后调用show()方法使其可见。
启动事件循环
return a.exec();
a.exec()进入主事件循环,处理用户输入(如鼠标、键盘事件)并分发至相应组件。
GUI应用程序的事件驱动机制
Qt采用事件驱动模型,用户交互(如按钮点击、键盘输入)触发事件,由对应控件处理。exec()确保应用程序持续响应事件直至退出。
3.5窗口相关文件
窗口界面设计和界面组件的事件处理是GUI程序设计的主要任务,在之后的示例中我们会介绍设计更复杂的界面。那么窗口的UI可视化设计结果是如何转换成代码,窗口时间如何与程序关联,这些设计窗口UI设计和程序运行的基本原理。
在Qt Creator的Project设置界面,取消勾选Shadow build复选框,然后以Release模式构建项目。项目构建后,项目根目录下会生成一个文件 ui_mainwindow.h.。这样与窗口有关的4个文件如表所示
| 文件 | 说明 |
|---|---|
| mainwindow.h | 定义了窗口类mainWindow |
| mainwindow.cpp | 实现mainwindow类功能的源程序文件 |
| mainwindow.ui | 窗口Ui文件,用于Qt Designer中进行UI可视化设计,mainwindow.ui是一个XML文件,存储界面上各个组件的属性和布局内容 |
| ui_mainwindow.h | 描述UI文件中界面组件的属性设置、布局以及信号与槽的关联等内容 |
| 1.mainwindow.h | |
| 定义主窗口类MainWindow,通常继承自QMainWindow或类似Qt窗口基类。声明窗口的成员变量、槽函数以及构造函数等核心接口。 |
//防止头文件被重复包含的预处理指令
//当第一次包含该头文件时,MAINWINDOW_H未被定义,会执行后续代码并定义该宏
//当再次包含时,由于该宏已定义,会跳过中间的底阿妈,避免重复
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
//创建Qt主窗口类文件,MainWIndow类继承自QMainWindow
#include <QMainWindow>
//Qt的命名空间声明,用于隔离Qt库中的类和函数
QT_BEGIN_NAMESPACE
//声明Ui命名空间中的MainWindow类,该类由Qt Designer自动生成
//用于访问UI界面中的各个空间
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
//自定义的窗口类,继承子QMainWIndow(Qt提供的主窗口基类)
class MainWindow : public QMainWindow {
Q_OBJECT//Qt元对象系统宏,用于支持信号与槽机制、运行时类型信息等
public:
//构造函数,创建MainWindows对象
//参数parent指定付窗口,默认为nullptr(无父窗口)
MainWindow(QWidget *parent = nullptr);
//构造函数;销毁MainWindows对象,释放资源
~MainWindow();
private slots:
/ 槽函数:当pushButton按钮被点击时会触发此函数
// 槽函数需要在private slots、protected slots或public slots部分声明
void on_pushButton_clicked();
private:
// 指向UI界面的指针,用于访问Qt Designer设计的界面元素
// Ui::MainWindow类包含了所有界面控件的成员变量
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
2.mainwindow.cpp
实现MainWindow类的功能逻辑,包括构造函数、槽函数和其他成员函数的具体实现。
// 包含对应的头文件,确保类的声明可见
#include "mainwindow.h"
// 包含UI自动生成的头文件,用于访问界面控件
#include "ui_mainwindow.h"
// MainWindow类的构造函数
// 参数parent:父窗口指针,用于Qt的对象树管理
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent) // 初始化父类QMainWindow
, ui(new Ui::MainWindow) // 初始化UI指针,创建Ui::MainWindow对象
{
// 调用UI的setupUi方法,将界面元素设置到当前窗口
// 该函数由Qt Designer自动生成,负责创建和布局所有界面控件
ui->setupUi(this);
}
// MainWindow类的析构函数
MainWindow::~MainWindow()
{
// 释放UI指针指向的对象,避免内存泄漏
// 由于ui是通过new创建的,必须在析构函数中手动释放
delete ui;
}
3.mainwindow.ui
XML格式的UI设计文件,通过Qt Designer进行可视化编辑。存储界面组件(如按钮、标签)的布局、属性和信号槽关联。
<?xml version="1.0" encoding="UTF-8"?>
<!-- UI文件版本声明,Qt Designer使用的UI格式版本为4.0 -->
<ui version="4.0">
<!-- 定义该UI对应的类名,与C++中的MainWindow类对应 -->
<class>MainWindow</class>
<!-- 主窗口部件定义,类型为QMainWindow,名称为MainWindow -->
<widget class="QMainWindow" name="MainWindow">
<!-- 窗口几何属性设置(位置和大小) -->
<property name="geometry">
<rect>
<x>0</x> <!-- 窗口左上角x坐标(相对于屏幕) -->
<y>0</y> <!-- 窗口左上角y坐标(相对于屏幕) -->
<width>800</width> <!-- 窗口宽度 -->
<height>600</height> <!-- 窗口高度 -->
</rect>
</property>
<!-- 窗口标题属性设置 -->
<property name="windowTitle">
<string>MainWindow</string> <!-- 窗口标题栏显示的文本 -->
</property>
<!-- 中央部件定义(QMainWindow必须包含一个中央部件) -->
<widget class="QWidget" name="centralwidget">
<!-- 标签部件定义,类型为QLabel,名称为label -->
<widget class="QLabel" name="label">
<!-- 标签的几何属性设置(位置和大小,相对于父部件) -->
<property name="geometry">
<rect>
<x>280</x> <!-- 标签左上角x坐标(相对于中央部件) -->
<y>150</y> <!-- 标签左上角y坐标(相对于中央部件) -->
<width>131</width> <!-- 标签宽度 -->
<height>71</height> <!-- 标签高度 -->
</rect>
</property>
<!-- 标签显示的文本内容 -->
<property name="text">
<!-- 使用HTML格式设置文本样式:20号字体,粗体,显示"Hello Qt" -->
<string><html><head/><body><p><span style=" font-size:20pt; font-weight:700;">Hello Qt</span></p></body></html></string>
</property>
</widget>
</widget>
<!-- 菜单栏定义,类型为QMenuBar,名称为menubar -->
<widget class="QMenuBar" name="menubar">
<!-- 菜单栏几何属性设置 -->
<property name="geometry">
<rect>
<x>0</x> <!-- 菜单栏左上角x坐标 -->
<y>0</y> <!-- 菜单栏左上角y坐标(位于窗口顶部) -->
<width>800</width> <!-- 菜单栏宽度(与窗口同宽) -->
<height>21</height> <!-- 菜单栏高度(Qt默认高度) -->
</rect>
</property>
</widget>
<!-- 状态栏定义,类型为QStatusBar,名称为statusbar -->
<widget class="QStatusBar" name="statusbar"/>
</widget>
<!-- 资源文件引用(当前无资源文件) -->
<resources/>
<!-- 信号与槽连接定义(当前无连接) -->
<connections/>
</ui>
更多推荐


所有评论(0)