GUI程序设计
GUI程序构建
QT程序构建原理
Qt项目构建过程基本原理
- 元对象系统和MOC
- UI文件和UIC
- 资源文件和RCC
元对象系统和MOC
- 元对象系统 :
- Qt的元对象系统提供了运行时类型信息和信号/槽机制,允许对象之间的动态交互。
- 提供了一项重要功能,允许开发者在运行时获取类的信息,如属性、方法等。
- MOC(Meta-Object Compiler) :
- MOC是Qt工具链的一部分,用于解析Qt特定的C++代码,生成元对象代码。
- MOC处理含有特定宏(如
QObject和Q_PROPERTY)的类,自动生成信号、槽和属性的支持代码。
UI文件和UIC
- UI文件 :
- UI文件是使用Qt Designer创建的文件,通常使用
.ui扩展名,定义了用户界面的布局和组件。 - 这些文件采用XML格式表示界面结构。
- UI文件是使用Qt Designer创建的文件,通常使用
- UIC(User Interface Compiler) :
- UIC是一个工具,用于将UI文件转换为C++代码,生成对应的用户界面类。
- 转换后的代码可以直接与其他C++代码进行集成,使开发者能够轻松创建和管理用户界面。
资源文件和RCC
- 资源文件 :
- 资源文件(.qrc)用于将图像、音频文件、文本等静态资源嵌入到应用程序中。
- 允许开发者在编译时将资源打包,以便在运行时访问。
- RCC(Resource Compiler) :
- RCC是一个工具,用于将资源文件编译成二进制格式,生成C++代码,以便于资源的访问和管理。
- 通过RCC,开发者可以在应用程序中通过简洁的路径访问资源,而不需要在磁盘上查找文件。
Qt项目构建过程
- 项目配置文件:包含项目的配置信息,如编译器设置、源文件路径等。
- Qt C++编写的文件:包括头文件和源程序文件。这些文件使用Qt库提供的类和功能进行编写。
- 窗口UI文件:描述窗口界面布局、控件属性等。这些文件会被转换为C++程序文件。
- 资源文件:包含项目中的图片、音频等资源。
构建过程中的机制:
- UI文件被转换为C++程序文件,并自动实现信号与槽的连接。
- 其他C++源文件被编译为标准C++语言的程序文件。
- 这些程序文件随后被标准C++编译器(如GNU C++编译器或MSVC编译器)编译成可执行文件或库。
- 在使用Qt的信号与槽机制的类中,必须插入宏Q_OBJECT。这个宏是Qt元对象系统的一部分,用于处理对象的元信息,如信号和槽的声明。
- 窗口UI文件的编译在构建项目时,可视化设计的窗口UI文件会被用户界面编译器(UIC)转换为一个C++源程序文件。UIC编译生成的文件与UI文件在同一个文件夹里,例如 ui_widget.h 在项目samp2_1的根目录下。文件ui_widget.h 之后会被标准C++编译器编译。
- 资源文件和RCCQt项目中的资源文件(.qrc文件)会被资源编译器(RCC)转换为C++程序文件。项目中的资源文件是res.qrc,经过RCC编译后生成的文件是qre_res.cpp(可以在release文件夹里看到)。文件qrc_res.cpp之后会被标准C++编译器编译。
Qt对标准C++的扩展------元对象系统(MOS)
Qt对标准C++语言进行了扩展,引入了元对象系统(MOS)。所有从QObject继承的类都可以利用元对象系统提供的功能。
元对象系统支持以下特性:
- 属性:为类提供动态的数据成员管理。
- 信号与槽:实现对象间的通信,是Qt的核心特性之一。
- 动态类型转换:允许在运行时进行对象类型的检查与转换。
使用MOC、UIC和RCC编译各原始文件的过程称为预编译过程,预编译之后生成的是标准C++语言的程序文件,它们被标准C++编译器编译和连接,最终生成可执行文件。


qmake
qmake作用
qmake是一个构建项目的工具软件,它根据项目配置文件中的设置生成Makefile文件。
qmake的主要是为了方便C++编译器的编译和连接工作。通过生成Makefile文件,C++编译器能够根据文件指示进行编译和连接,从而实现项目的构建。
如果使用qmake构建系统,就会生成一个后缀为.pro的项目配置文件
qmake在Qt项目中的应用
1. Qt项目的特殊配置
对于Qt项目,qmake除了生成基本的Makefile文件外,还会自动为元对象编译器(MOC)和用户界面编译器(UIC)生成构建规则。这些编译器是Qt项目中特有的,用于处理Qt的元对象和用户界面文件。
2. 项目配置文件
Qt项目的配置文件是自动生成的,但读者需要能够读懂其基本意义。这些配置文件中包含了项目的各种设置和依赖关系,是项目构建的基础。
3. 配置文件中的要素
配置文件中,"#"用于标识注释语句,方便用户理解和修改配置。配置文件中还包含了一些全大写的单词,这些是qmake配置文件中的变量,用于定义项目的各种属性和设置。
以一个Qt项目为例,qmake根据项目的配置文件自动生成了Makefile文件和其他必要的构建规则。在项目开发过程中,开发者无需手动修改这些配置文件(一般情况),但需要理解其含义和作用,以便于进行项目的管理和维护。
当项目需要添加新的源文件或修改编译设置时,只需在配置文件中做出相应的修改,qmake便会自动更新Makefile和其他构建规则,实现项目的快速构建和部署。
常见qmake配置文件变量及其含义的表格:
| 变量 | 含义 |
|---|---|
| TEMPLATE | 指定项目类型。常见的值有app(应用程序)和lib(库)。 |
| TARGET | 指定生成的目标文件(可执行文件或库文件)的名称。 |
| DESTDIR | 指定生成的目标文件存放的目录。 |
| SOURCES | 指定项目中的源代码文件列表。 |
| HEADERS | 指定项目中的头文件列表。 |
| FORMS | 指定项目中的用户界面文件(如Qt Designer生成的UI文件)列表。 |
| LIBS | 指定项目链接的库。可以包含库的名称和路径。 |
| INCLUDEPATH | 指定编译时搜索头文件的路径列表。 |
| DEPENDPATH | 指定编译时搜索依赖文件的路径列表。 |
| Qt | 指定项目使用的Qt模块列表(例如:Qt = core gui network)。 |
| CONFIG | 指定项目的配置选项,如debug、release、staticlib等。 |
| LIBS += -L/path/to/libs -llibname | 手动添加库和库路径。-L指定库文件路径,-l指定库名。 |
| DESTDIR += $$PWD/release/ | 设置生成文件的目录,其中$$PWD是当前项目路径。 |
| TARGET = myapp-$${TARGET_ARCH} | 设置目标文件名,可使用变量${TARGET_ARCH}改变。 |
| RC_FILE | 指定资源文件(如Windows程序的资源文件),包括程序图标和版本信息等。 |
变量Qt可用于定义项目中用到的Qt模块。如果项目中需要用到Qt框架中的一些附加模块,需要在项目配置文件中将模块加入Qt变量。例如要在项目中使用Qt SQL 模块,就需要在项目配置文件中加入如下的一行语句;
plain
Qt +=sql
qmake中提供替换函数(replace function)用于在配置过程中处理变量或内置函数的值,"$$"是替换函数的前缀,后面可以是变量名或qmake 的一些内置函数。例如下面的一行语句:
qnx: target .path = i tmp/$$ {TARGET}/bin
其中的"TARGET"就是替换函数,表示用变量TARGET的值替换。将" {TARGET}"就是替换函数,表示用变量TARGET的值替换。将" TARGET"就是替换函数,表示用变量TARGET的值替换。将" {TARGET}"写成" $$TARGET"也是可以的。
项目配置文件
Qt项目配置文件通常是指使用Qt Creator进行开发时生成的.pro文件。这些文件用于配置项目的构建和编译选项,使得开发者能够轻松地管理项目设置和依赖关系。
Qt项目配置文件的一些主要组成部分:
- 项目设置:
plain
TEMPLATE = app # 指定项目类型(如应用程序或库)
TARGET = MyApp # 输出的可执行文件名
- 源文件和头文件:
plain
SOURCES += main.cpp # 指定源文件
HEADERS += mainwindow.h # 指定头文件
- 资源文件:
plain
RESOURCES += resources.qrc # 指定资源文件
- 模块依赖:
plain
QT += core gui # 指定使用的Qt模块
- 配置选项:可以根据需要添加编译选项和其他设置,包括编译器和平台特定的选项。
- 变量定义 :可以在
.pro文件中定义变量,以便在项目中重复使用。 - 条件编译:
plain
# 根据构建类型添加特定库
win32: LIBS += -lws2_32 # Windows下链接特定库
示例:一个简单的.pro文件。
plain
TEMPLATE = app # 指定这是一个应用程序模板
TARGET = MyApp # 设置目标应用程序的名称
Qt += core gui # 指定项目需要的Qt模块
SOURCES += main.cpp \ # 源文件列表
QWidget.cpp \ # 其他源文件列表...
HEADERS += QWidget.h \ # 头文件列表...
FORMS += QWidget.ui # UI设计文件列表...
通过修改.pro文件,开发者可以轻松地调整项目的构建配置,在不同平台或不同环境下都能正确构建和测试应用程序。
Qt Creator的集成开发环境提供了图形界面来帮助管理这些配置文件。
UI文件
Qt的UI文件是使用Qt Designer设计的用户界面文件,通常以.ui为后缀。
这些文件包含了用户界面的布局、控件、属性以及其他视觉元素,用于构建图形用户界面(GUI)应用程序。
Qt Designer是一个可视化界面设计工具,允许开发者通过拖放的方式创建用户界面。
Qt的UI文件
Qt的UI文件使用XML格式,包含了关于界面布局和控件的元数据。这些文件可以被Qt的MOC(元对象编译器)处理,以生成用于交互的C++代码。开发者可以在他们的应用程序代码中集成这些UI元素。
如何使用UI文件
- 安装Qt Creator和Qt库:首先,需要安装Qt Creator开发环境和Qt库。Qt Creator内置了Qt Designer。
- 创建UI文件 :在Qt Creator中,可以通过新建项目并选择"Qt Widgets应用程序"或"Qt Quick应用程序"来创建一个新的UI文件。也可以直接打开Qt Designer并创建一个新的
.ui文件。 - 可视化设计:在Qt Designer中,可以通过拖放控件(如按钮、文本框、列表等)到设计窗口来创建界面。可以设置控件的属性(如文本、颜色、大小等)来定制界面。
- 集成到应用程序中 :一旦完成了UI设计,可以通过Qt的uic工具将
.ui文件转换为C++头文件。然后,可以在应用程序代码中使用这些生成的类来访问和操作UI元素。
主程序文件
主程序组成
- 主窗口文件(widget.h/.cpp)
- 程序入口文件(main.cpp)
- 用户界面文件(.ui 文件)
- 资源文件(.qrc 文件)
- 头文件(.h)
- 实现文件(.cpp)
如果创建的是QWidget,则默认是widget.h和widget.cpp


main.cpp
这是应用程序的入口点,包含 main() 函数。
示例:
cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show(); //展示窗口
return a.exec();
}
解释:
QApplication: 管理GUI应用程序的控制流和主要设置。Widget: 自定义的主窗口类。app.exec(): 启动应用程序的事件循环。
widget.h
包含主窗口的类定义,继承自 QWidget。
在文件widget.h中,定义了Widget类。这个类中定义了一个类型为Ui::Widget的指针变量ui。这个指针的作用是访问界面上的所有组件,因为Ui::Widget类中界面组件对象都是公有成员。
示例:
cpp
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
QT_BEGIN_NAMESPACE
namespace Ui {
class Widget;
}
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
解释:
QWidget: 主窗口的基类,提供了常见窗口布局的功能。Ui::Widget: 引用 UI 文件中自动生成的界面元素。
widget.cpp
实现主窗口的构造函数和析构函数。
构造函数与界面初始化
Widget类的构造函数用于创建Ui::Widget类的对象ui,并通过调用 ui->setupUi(this) 进行窗口界面的初始化。这个过程中,会创建所有的界面组件、设置属性以及设置信号与槽的关联。
- 这里的"this"指的是Widget实例对象,它是一个QWidget窗口,是setupUi(this)中创建的所有界面组件的父容器。
通过ui指针访问界面组件
在Widget类中编写程序时,开发者可以通过ui指针访问窗口界面上的所有组件。这个指针提供了一个便捷的方式,用于操作和修改界面上的元素。
修改Widget类构造函数完成特定界面需求
可以在此处插入具体修改构造函数的事例,描述如何通过修改构造函数来实现特定的功能或优化
Widget类是Qt框架中用于创建和管理图形用户界面的一个重要类。
执行构造函数,Widget类的实例会创建Ui::Widget对象并调用其setupUi方法进行界面初始化,包括创建组件、设置属性和信号槽的关联等操作。
Widget类的实例(this)作为父容器,承载了由setupUi方法创建的所有组件。
示例:
cpp
#include "widget.h"
#include "ui_widget.h" //
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this); //调用 ui->setupUi(this) 进行窗口界面的初始化
}
Widget::~Widget()
{
delete ui;
}
解释:
setupUi(this): 连接界面元素到当前对象。界面元素在ui_widget.h文件中- 析构函数释放动态分配的内存以防止内存泄漏。
.ui 文件
GUI 界面的 XML 格式文件,由 Qt Designer 创建,通常不需要手动编辑。存储了界面上所有组件的属性设置,布局,信号和槽函数的关联等内容
.ui文件 通过 uic 工具自动生成 C++ 代码 (ui_widget.h)。
示例:
xml
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Widget</class>
<widget class="QWidget" name="Widget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>Widget</string>
</property>
</widget>
<resources/>
<connections/>
</ui>
解释:定义了一个包含一个按钮的主窗口界面。
资源文件(.qrc)
用于管理图像、音频文件等资源,便于在应用程序中使用。
示例:
xml
<RCC>
<qresource prefix="/">
<file>images/logo.png</file>
</qresource>
</RCC>
解释:通过 qrc 文件管理资源,方便在代码中引用。
ui_widget.h
在构建项目时,UI文件Qwidget.ui 会被Qt的UIC编译为对应的C++语言头文件ui_widget.h。
这个文件并不会出现在Q Creator 的项目管理目录树里,它是构建项目时的一个中间文件。
- 当构建项目的时候会出现在debug或者release文件中。
ui_widget.h 主要工作:
- Ui_Widget类的定义与特性:
- Ui_Widget是一个用于封装可视化设计的界面的类。
- 该类没有父类,不是从QWidget继承而来,因此不是一个窗口类。
- Ui_Widget类的public部分为界面上的每个组件定义了一个指针变量,这些变量的名称与UI可视化设计时为组件设置的对象名称相匹配。
- setupUi()函数的作用:
setupUi()函数是Ui_Widget类中的一个重要函数,用于设置和创建界面组件。- 函数的第一个部分用于设置Widget(一个空的QWidget类型窗口)的一些属性,这些属性在Qt Designer中定义。
- 函数的第二部分用于创建界面组件,并设置其属性。使用
connect()函数实现信号与槽的关联,即将按钮的clicked信号与窗口的close槽函数关联,实现点击按钮关闭窗口的功能。
- 名字空间:
- 定义了名字空间
Ui,用于区分不同文件或模块中的类。 - 定义了一个从Ui_Widget继承的类
Widget,并将其放在Ui名字空间中。这样即使有同名类,也可以通过名字空间进行区分。
- 定义了名字空间
文件ui_widget.h的完整内容如下。
cpp
/********************************************************************************
** Form generated from reading UI file 'widget.ui'
**
** Created by: Qt User Interface Compiler version 6.8.0
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/
#ifndef UI_WIDGET_H
#define UI_WIDGET_H
#include <QtCore/QVariant>
#include <QtWidgets/QApplication>
#include <QtWidgets/QWidget>
QT_BEGIN_NAMESPACE
class Ui_Widget
{
public:
void setupUi(QWidget *Widget)
{
if (Widget->objectName().isEmpty())
Widget->setObjectName("Widget");
Widget->resize(800, 600);
retranslateUi(Widget);
QMetaObject::connectSlotsByName(Widget);
} // setupUi
void retranslateUi(QWidget *Widget)
{
Widget->setWindowTitle(QCoreApplication::translate("Widget", "Widget", nullptr));
} // retranslateUi
};
namespace Ui {
class Widget: public Ui_Widget {};
} // namespace Ui
QT_END_NAMESPACE
#endif // UI_WIDGET_H
UI设计
两种方法设计的对比:
| 对比项目 | 可视化设计程序 | 纯代码创建程序 |
|---|---|---|
| 代码文件 | 生成的UI文件(.ui),通过UIC转换为C++代码 | 直接编写C++文件(.cpp和.h) |
| 文件生成 | 需要额外的UI文件引入及UIC处理 | 无需额外文件,所有在C++代码中完成 |
| 开发效率 | 更高,拖拽组件和设置属性简单 | 可能较低,特别是复杂界面时 |
| 灵活性 | 限制于UI设计工具的功能 | 非常灵活,能够细致控制每个组件的行为 |
| 调试难度 | UI文件不直接显示逻辑,调试可能较复杂 | 逻辑与界面皆在代码中,调试较为直接 |
| 可读性 | UI定义在.ui文件中,代码部分可能较清晰 | UI与逻辑混合在代码中,可读性可能降低 |
| 重新设计 | 改动UI容易,界面更新直观 | 改动时需要手动调整更多代码 |
| 学习曲线 | 对新手友好,容易上手 | 需要了解Qt控件与布局等知识 |
可视化UI设计
Qt Designer的主要功能区域:
| 组件名称 | 位置及描述 |
|---|---|
| 组件面板 | 位于窗口左侧,包含Layouts(布局)、Buttons(按钮)、Display Widgets(显示部件)等各类常用组件 |
| 待设计窗体 | 位于窗口中间,用于放置和布局各种组件,可通过拖拽组件到窗体上快速添加和排列 |
| Action编辑器 | 位于待设计窗体下方,用于可视化设计Action,方便定义和编辑动作 |
| 信号与槽编辑器 | 位于待设计窗体下方,用于可视化地进行信号与槽的关联,实现界面组件之间的交互 |
| 布局和界面设计工具栏 | 位于窗口上方,提供多种布局和界面设计的工具,帮助快速实现各种界面效果 |
| 对象检查器 | 位于窗口右侧上方,以树状视图显示窗体上各组件的布局和层级关系 |
| 属性编辑器 | 位于窗口右侧下方,显示选中的组件或窗体的各种属性,可在其中修改属性的值以实现界面的自定义 |
Qt Designer 界面如下:


创建项目
创建项目:
- 打开Qt Creator,选择"New File or Project"对话框。
- 在向导中选择qmake构建系统。
- 选择窗口基类为QDialog,创建的窗口类名称默认设置为Dialog。
- 勾选"Generate form"复选框,以便Qt Creator自动创建UI文件。
- 完成创建后,项目文件夹中会有dialog.ui文件。
创建资源文件
创建资源文件:
- 在项目的根目录下创建一个名为"images"的文件夹,用于存放图标文件。
- 在Qt Creator中,再次打开"New File or Project"对话框。
- 选择Qt分组里的"Qt Resource File"。
- 按照向导指引设置资源文件的文件名,并将其添加到当前项目中。例如,创建名为res.qrc的资源文件。
- 在项目管理目录树里,会看到一个名为"Resources"的文件组,打开它可以看到刚刚创建的资源文件。
- 在资源文件编辑器中,添加资源前缀,例如"icons",表示资源的分组。
伙伴关系
伙伴关系是一种用于增强界面组件之间交互的机制。
- 定义:伙伴关系通常指一个控件与另一个控件之间的关联,允许它们在用户交互时互相作用。例如,一个输入框和其旁边的标签或者按钮之间的关系。
如何设置伙伴关系
- 使用
setBuddy()方法:可通过设置一个控件的伙伴(如 QLineEdit 的伙伴可以是 QLabel ),使得在用户按下Tab键时,焦点自动转移到伙伴控件。
cpp
QLabel* label = new QLabel("Name:");
QLineEdit* lineEdit = new QLineEdit;
lineEdit->setBuddy(label); // 设置伙伴关系
视觉和交互效果
- 提高可用性:伙伴关系可以改善用户界面,确保界面元素之间的逻辑关系更加清晰,让用户在操作时更加便捷。
- 提示和验证:输入框的提示文本可以利用伙伴关系与标签结合,提升输入的准确性。
适用场景
- 常见于表单、对话框等地方,帮助用户在填写信息时更容易理解各个控件的作用。
主要应用
- 焦点管理:当一个控件获得焦点时,其伙伴控件通常会更新状态,例如显示提示信息或进行其他相关操作。
- 可见性联动:如果一个控件被隐藏,其伙伴控件也可能会根据需求进行隐藏或变更状态。
示例代码
以下是一个简单的示例,演示如何在Qt中使用伙伴关系:
cpp
#include <QApplication>
#include <QWidget>
#include <QLabel>
#include <QLineEdit>
#include <QVBoxLayout>
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
// 创建主窗口
QWidget window;
window.setWindowTitle("Buddy Relationship Example");
// 创建标签和输入框
QLabel *label = new QLabel("Name:");
QLineEdit *lineEdit = new QLineEdit;
// 设置伙伴关系
label->setBuddy(lineEdit);
// 创建布局并添加组件
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(label);
layout->addWidget(lineEdit);
window.setLayout(layout);
window.show();
return app.exec();
}
代码说明
- 创建QLabel和QLineEdit:创建一个标签和一个输入框。
- 设置伙伴关系 :调用
label->setBuddy(lineEdit)方法来建立伙伴关系。 - 使用布局管理器 :使用
QVBoxLayout将这些组件垂直排列。
效果
当用户在窗口中按下Tab键时,输入框会获得焦点。同时,标签可以通过访问setBuddy()方法使用户清楚哪个输入框是与之相关的。
代码化UI设计
窗口界面的可视化设计是对用户而言的,UI文件都会被UIC转换为C++程序文件。
- 如果不使用Qt Designer进行UI可视化设计,直接编写C++代码也是可以创建界面的,而且某些界面效果是可视化设计无法实现的。
- 如果习惯了用纯代码的方式设计界面,就可以采用纯代码的方式创建界面。Qt自带的示例项目基本都是用纯代码方式创建UI。

代码化创建项目的步骤:
- 选择 File > New File or Project。
- 选择 Application > Qt Widgets Application ,然后点击 Choose。
- 输入项目名称和位置,点击 Next。构建窗口是不勾选Generate form复选框,这样项目没有ui文件
- 选择构建工具,点击 Finish。
- 编写代码
- 编译运行
这样操作步骤过后,项目结构大致如下:
plain
MyQtApp/
├── MyQtApp.pro
├── main.cpp
可以根据需要添加更多的组件和功能。可利用 Qt 提供的各种控件(如文本框、标签等)和信号槽机制来增强应用程序的功能。
容器组件被删除时,其内部组件也会自动删除
示例:简单的代码化设计。直接在main.cpp中编写代码
cpp
#include <QApplication>
#include <QPushButton>
#include <QWidget>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
// 创建一个窗口
QWidget window;
window.resize(400, 300); // 设置窗口大小
window.setWindowTitle("My First Qt GUI App"); // 设置窗口标题
// 创建一个按钮
QPushButton *button = new QPushButton("Click Me!", &window);
button->setGeometry(150, 130, 100, 30); // 设置按钮位置和大小
// 显示窗口
window.show();
return app.exec(); // 进入应用程序主循环
}
运行结果:

CMake构建系统
基本概念
- CMake:一种跨平台的构建系统生成工具,用于管理项目的编译过程。
- CMakeLists.txt:CMake的配置文件,包含构建逻辑和参数设置。
设置Qt项目的CMake构建流程
- 创建项目目录:在你的工作目录中创建一个新文件夹作为项目目录。
- 创建CMakeLists.txt文件 :
在项目根目录下创建一个名为CMakeLists.txt的文件,内容示例如下:
cmake
cmake_minimum_required(VERSION 3.10)
# 设置项目名称和版本
project(MyQtApp VERSION 1.0 LANGUAGES CXX)
# 查找Qt库
find_package(Qt5 COMPONENTS Widgets REQUIRED)
# 添加可执行文件
add_executable(MyQtApp main.cpp)
# 链接Qt库
target_link_libraries(MyQtApp Qt5::Widgets)
# 设置C++标准
set_target_properties(MyQtApp PROPERTIES
CXX_STANDARD 11
CXX_STANDARD_REQUIRED ON)
- 编写源文件 :
在项目目录中创建源文件,例如main.cpp,内容简单示例如下:
cpp
#include <QApplication>
#include <QPushButton>
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QPushButton button("Hello, Qt with CMake!");
button.resize(200, 100);
button.show();
return app.exec();
}
构建项目
- 创建构建目录 :
在项目根目录下创建一个名为build的子目录:
bash
mkdir build
cd build
- 运行CMake配置 :
在构建目录中运行CMake指令:
bash
cmake ..
这将读取CMakeLists.txt并生成构建文件。
- 编译项目 :
运行编译命令(例如使用make):
bash
make
- 运行可执行文件 :
编译完成后,可以在build目录中找到生成的可执行文件,运行它:
bash
./MyQtApp
使用CMake构建Qt项目具有以下优势:
- 跨平台支持:CMake可以在不同的操作系统上生成相应的构建文件。
- 简化依赖管理:CMake可以更容易地管理项目依赖。
- 更好的集成:与现代IDE(如Qt Creator、Visual Studio等)良好集成。
CMake项目是用CMake语言写的一些文件,项目的主文件是CMakeLists.txt,它被放置在Qt项目源程序文件的根目录下。
参考案例
示例:可视化设计一个界面
main.cpp
cpp
#include "dialog.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Dialog w;
w.show();
return a.exec();
}
dialog.h
cpp
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
QT_BEGIN_NAMESPACE
namespace Ui { class Dialog; }
QT_END_NAMESPACE
class Dialog : public QDialog
{
Q_OBJECT
public:
Dialog(QWidget *parent = nullptr);
~Dialog();
private slots:
void do_setFontColor(); //设置字体颜色
void on_chkBoxUnder_clicked(bool checked);
void on_chkBoxItalic_clicked(bool checked);
void on_chkBoxBold_clicked(bool checked);
void on_btnClear_clicked();
private:
Ui::Dialog *ui;
};
#endif // DIALOG_H
dialog.cpp
cpp
#include "dialog.h"
#include "ui_dialog.h"
Dialog::Dialog(QWidget *parent)
: QDialog(parent)
, ui(new Ui::Dialog)
{
ui->setupUi(this);
connect(ui->radioBlack,SIGNAL(clicked()),this,SLOT(do_setFontColor()));
connect(ui->radioRed, SIGNAL(clicked()),this,SLOT(do_setFontColor()));
connect(ui->radioBlue, SIGNAL(clicked()),this,SLOT(do_setFontColor()));
}
Dialog::~Dialog()
{
delete ui;
}
void Dialog::do_setFontColor()
{
//自定义槽函数,设置文字颜色
QPalette plet=ui->plainTextEdit->palette();
if (ui->radioBlue->isChecked())
plet.setColor(QPalette::Text,Qt::blue);
else if (ui->radioRed->isChecked())
plet.setColor(QPalette::Text,Qt::red);
else if (ui->radioBlack->isChecked())
plet.setColor(QPalette::Text,Qt::black);
else
plet.setColor(QPalette::Text,Qt::black);
ui->plainTextEdit->setPalette(plet);
}
void Dialog::on_chkBoxUnder_clicked(bool checked)
{
//Underline 复选框
QFont font=ui->plainTextEdit->font();
font.setUnderline(checked);
ui->plainTextEdit->setFont(font);
}
void Dialog::on_chkBoxItalic_clicked(bool checked)
{
//Italic 复选框
QFont font=ui->plainTextEdit->font();
font.setItalic(checked);
ui->plainTextEdit->setFont(font);
}
void Dialog::on_chkBoxBold_clicked(bool checked)
{
// Bold 复选框
QFont font=ui->plainTextEdit->font();
font.setBold(checked);
ui->plainTextEdit->setFont(font);
}
void Dialog::on_btnClear_clicked()
{
//"清空"按钮
ui->plainTextEdit->clear();
}
示例:代码化设计一个界面
main.cpp
cpp
//main.cpp
#include "dialog.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Dialog w;
w.show();
return a.exec();
}
dialog.h
cpp
//dialog.h
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include <QCheckBox>
#include <QRadioButton>
#include <QPlainTextEdit>
#include <QPushButton>
//#include <QVBoxLayout>
class Dialog : public QDialog
{
Q_OBJECT
private:
QCheckBox *chkBoxUnder;
QCheckBox *chkBoxItalic;
QCheckBox *chkBoxBold;
QRadioButton *radioBlack;
QRadioButton *radioRed;
QRadioButton *radioBlue;
QPlainTextEdit *txtEdit;
QPushButton *btnOK;
QPushButton *btnCancel;
QPushButton *btnClose;
void iniUI(); //UI创建与初始化
void iniSignalSlots(); //初始化信号与槽的链接
private slots:
void do_chkBoxUnder(bool checked); //Underline
void do_chkBoxItalic(bool checked); //Italic
void do_chkBoxBold(bool checked); //Bold
void do_setFontColor(); //设置文字颜色
public:
Dialog(QWidget *parent = nullptr);
~Dialog();
};
#endif // DIALOG_H
dialog.cpp
c
#include "dialog.h"
#include <QHBoxLayout>
#include <QVBoxLayout>
void Dialog::iniUI()
{
//创建 Underline, Italic, Bold三个 CheckBox,并水平布局
chkBoxUnder=new QCheckBox("Underline");
chkBoxItalic=new QCheckBox("Italic");
chkBoxBold=new QCheckBox("Bold");
QHBoxLayout *HLay1=new QHBoxLayout();
HLay1->addWidget(chkBoxUnder);
HLay1->addWidget(chkBoxItalic);
HLay1->addWidget(chkBoxBold);
//创建 Black, Red, Blue三个 RadioButton,并水平布局
radioBlack=new QRadioButton("Black");
radioBlack->setChecked(true); //缺省被选中
radioRed=new QRadioButton("Red");
radioBlue=new QRadioButton("Blue");
QHBoxLayout *HLay2=new QHBoxLayout;
HLay2->addWidget(radioBlack);
HLay2->addWidget(radioRed);
HLay2->addWidget(radioBlue);
//创建 确定, 取消, 退出 三个 PushButton, 并水平布局
btnOK=new QPushButton("确定");
btnCancel=new QPushButton("取消");
btnClose=new QPushButton("退出");
QHBoxLayout *HLay3=new QHBoxLayout;
HLay3->addStretch();
HLay3->addWidget(btnOK);
HLay3->addWidget(btnCancel);
HLay3->addStretch();
HLay3->addWidget(btnClose);
//创建 文本框,并设置初始字体
txtEdit=new QPlainTextEdit;
txtEdit->setPlainText("Hello world\n手工创建");
QFont font=txtEdit->font(); //获取字体
font.setPointSize(20); //修改字体大小为20
txtEdit->setFont(font); //设置字体
//创建 垂直布局,并设置为主布局
// VLay=new QVBoxLayout(this);
QVBoxLayout *VLay=new QVBoxLayout(this);
VLay->addLayout(HLay1); //添加字体类型组
VLay->addLayout(HLay2); //添加字体颜色组
VLay->addWidget(txtEdit); //添加PlainTextEdit
VLay->addLayout(HLay3); //添加按键组
setLayout(VLay); //设置为窗口的主布局
}
void Dialog::iniSignalSlots()
{
//三个设置颜色的 QRadioButton
connect(radioBlue,SIGNAL(clicked()),this,SLOT(do_setFontColor()));
connect(radioRed,SIGNAL(clicked()),this,SLOT(do_setFontColor()));
connect(radioBlack,SIGNAL(clicked()),this,SLOT(do_setFontColor()));
//三个设置字体的 QCheckBox
connect(chkBoxUnder,SIGNAL(clicked(bool)),this,SLOT(do_chkBoxUnder(bool)));
connect(chkBoxItalic,SIGNAL(clicked(bool)),this,SLOT(do_chkBoxItalic(bool)));
connect(chkBoxBold,SIGNAL(clicked(bool)),this,SLOT(do_chkBoxBold(bool)));
//三个按钮与窗口的槽函数关联
connect(btnOK,SIGNAL(clicked()),this,SLOT(accept()));
connect(btnCancel,SIGNAL(clicked()),this,SLOT(reject()));
connect(btnClose,SIGNAL(clicked()),this,SLOT(close()));
}
void Dialog::do_chkBoxUnder(bool checked)
{
QFont font=txtEdit->font();
font.setUnderline(checked);
txtEdit->setFont(font);
}
void Dialog::do_chkBoxItalic(bool checked)
{
QFont font=txtEdit->font();
font.setItalic(checked);
txtEdit->setFont(font);
}
void Dialog::do_chkBoxBold(bool checked)
{
QFont font=txtEdit->font();
font.setBold(checked);
txtEdit->setFont(font);
}
void Dialog::do_setFontColor()
{
QPalette plet=txtEdit->palette();
if (radioBlue->isChecked())
plet.setColor(QPalette::Text,Qt::blue);
else if (radioRed->isChecked())
plet.setColor(QPalette::Text,Qt::red);
else if (radioBlack->isChecked())
plet.setColor(QPalette::Text,Qt::black);
else
plet.setColor(QPalette::Text,Qt::black);
txtEdit->setPalette(plet);
}
Dialog::Dialog(QWidget *parent)
: QDialog(parent)
{
iniUI(); //界面创建与布局
iniSignalSlots(); //信号与槽的关联
setWindowTitle("创建UI"); //设置窗口标题
}
Dialog::~Dialog()
{
}
示例:为应用程序设置图标
项目被构建后生成的可执行文件具有默认的图标,如果需要为应用程序设置图标,可按如下步骤操作。
(1)将一个后缀为".ico"的图标文件复制到项目根目录下,假设图标文件名是editor.ico。
(2)在项目配置文件(.pro文件)里用RC_ICONS 设置图标文件名,即添加如下一行语句;RC_ICONS = editor.ico
重新构建项目,生成的可执行文件以及窗口的图标就会换成设置的图标。