重学Qt——GUI程序设计

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格式表示界面结构。
  • UIC(User Interface Compiler) :
    • UIC是一个工具,用于将UI文件转换为C++代码,生成对应的用户界面类。
    • 转换后的代码可以直接与其他C++代码进行集成,使开发者能够轻松创建和管理用户界面。

资源文件和RCC

  • 资源文件 :
    • 资源文件(.qrc)用于将图像、音频文件、文本等静态资源嵌入到应用程序中。
    • 允许开发者在编译时将资源打包,以便在运行时访问。
  • RCC(Resource Compiler) :
    • RCC是一个工具,用于将资源文件编译成二进制格式,生成C++代码,以便于资源的访问和管理。
    • 通过RCC,开发者可以在应用程序中通过简洁的路径访问资源,而不需要在磁盘上查找文件。

Qt项目构建过程

  1. 项目配置文件:包含项目的配置信息,如编译器设置、源文件路径等。
  2. Qt C++编写的文件:包括头文件和源程序文件。这些文件使用Qt库提供的类和功能进行编写。
  3. 窗口UI文件:描述窗口界面布局、控件属性等。这些文件会被转换为C++程序文件。
  4. 资源文件:包含项目中的图片、音频等资源。

构建过程中的机制:

  • 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继承的类都可以利用元对象系统提供的功能。

元对象系统支持以下特性:

  1. 属性:为类提供动态的数据成员管理。
  2. 信号与槽:实现对象间的通信,是Qt的核心特性之一。
  3. 动态类型转换:允许在运行时进行对象类型的检查与转换。

使用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项目配置文件的一些主要组成部分:

  1. 项目设置:
plain 复制代码
TEMPLATE = app  # 指定项目类型(如应用程序或库)
TARGET = MyApp  # 输出的可执行文件名
  1. 源文件和头文件:
plain 复制代码
SOURCES += main.cpp  # 指定源文件
HEADERS += mainwindow.h  # 指定头文件
  1. 资源文件:
plain 复制代码
RESOURCES += resources.qrc  # 指定资源文件
  1. 模块依赖:
plain 复制代码
QT += core gui  # 指定使用的Qt模块
  1. 配置选项:可以根据需要添加编译选项和其他设置,包括编译器和平台特定的选项。
  2. 变量定义 :可以在 .pro 文件中定义变量,以便在项目中重复使用。
  3. 条件编译:
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文件

  1. 安装Qt Creator和Qt库:首先,需要安装Qt Creator开发环境和Qt库。Qt Creator内置了Qt Designer。
  2. 创建UI文件 :在Qt Creator中,可以通过新建项目并选择"Qt Widgets应用程序"或"Qt Quick应用程序"来创建一个新的UI文件。也可以直接打开Qt Designer并创建一个新的.ui文件。
  3. 可视化设计:在Qt Designer中,可以通过拖放控件(如按钮、文本框、列表等)到设计窗口来创建界面。可以设置控件的属性(如文本、颜色、大小等)来定制界面。
  4. 集成到应用程序中 :一旦完成了UI设计,可以通过Qt的uic工具将.ui文件转换为C++头文件。然后,可以在应用程序代码中使用这些生成的类来访问和操作UI元素。

主程序文件

主程序组成

  1. 主窗口文件(widget.h/.cpp)
  2. 程序入口文件(main.cpp)
  3. 用户界面文件(.ui 文件)
  4. 资源文件(.qrc 文件)
  5. 头文件(.h)
  6. 实现文件(.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 主要工作:

  1. Ui_Widget类的定义与特性:
    • Ui_Widget是一个用于封装可视化设计的界面的类。
    • 该类没有父类,不是从QWidget继承而来,因此不是一个窗口类。
    • Ui_Widget类的public部分为界面上的每个组件定义了一个指针变量,这些变量的名称与UI可视化设计时为组件设置的对象名称相匹配。
  2. setupUi()函数的作用:
    • setupUi()函数是Ui_Widget类中的一个重要函数,用于设置和创建界面组件。
    • 函数的第一个部分用于设置Widget(一个空的QWidget类型窗口)的一些属性,这些属性在Qt Designer中定义。
    • 函数的第二部分用于创建界面组件,并设置其属性。使用connect()函数实现信号与槽的关联,即将按钮的clicked信号与窗口的close槽函数关联,实现点击按钮关闭窗口的功能。
  3. 名字空间:
    • 定义了名字空间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 界面如下:


创建项目

创建项目:

  1. 打开Qt Creator,选择"New File or Project"对话框。
  2. 在向导中选择qmake构建系统。
  3. 选择窗口基类为QDialog,创建的窗口类名称默认设置为Dialog。
  4. 勾选"Generate form"复选框,以便Qt Creator自动创建UI文件。
  5. 完成创建后,项目文件夹中会有dialog.ui文件。
创建资源文件

创建资源文件:

  1. 在项目的根目录下创建一个名为"images"的文件夹,用于存放图标文件。
  2. 在Qt Creator中,再次打开"New File or Project"对话框。
  3. 选择Qt分组里的"Qt Resource File"。
  4. 按照向导指引设置资源文件的文件名,并将其添加到当前项目中。例如,创建名为res.qrc的资源文件。
  5. 在项目管理目录树里,会看到一个名为"Resources"的文件组,打开它可以看到刚刚创建的资源文件。
  6. 在资源文件编辑器中,添加资源前缀,例如"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();
}

代码说明

  1. 创建QLabel和QLineEdit:创建一个标签和一个输入框。
  2. 设置伙伴关系 :调用label->setBuddy(lineEdit)方法来建立伙伴关系。
  3. 使用布局管理器 :使用QVBoxLayout将这些组件垂直排列。

效果

当用户在窗口中按下Tab键时,输入框会获得焦点。同时,标签可以通过访问setBuddy()方法使用户清楚哪个输入框是与之相关的。

代码化UI设计

窗口界面的可视化设计是对用户而言的,UI文件都会被UIC转换为C++程序文件。

  • 如果不使用Qt Designer进行UI可视化设计,直接编写C++代码也是可以创建界面的,而且某些界面效果是可视化设计无法实现的。
  • 如果习惯了用纯代码的方式设计界面,就可以采用纯代码的方式创建界面。Qt自带的示例项目基本都是用纯代码方式创建UI。

代码化创建项目的步骤:

  1. 选择 File > New File or Project。
  2. 选择 Application > Qt Widgets Application ,然后点击 Choose。
  3. 输入项目名称和位置,点击 Next。构建窗口是不勾选Generate form复选框,这样项目没有ui文件
  4. 选择构建工具,点击 Finish。
  5. 编写代码
  6. 编译运行

这样操作步骤过后,项目结构大致如下:

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构建系统

基本概念

  1. CMake:一种跨平台的构建系统生成工具,用于管理项目的编译过程。
  2. CMakeLists.txt:CMake的配置文件,包含构建逻辑和参数设置。

设置Qt项目的CMake构建流程

  1. 创建项目目录:在你的工作目录中创建一个新文件夹作为项目目录。
  2. 创建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)
  1. 编写源文件 :
    在项目目录中创建源文件,例如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();
}

构建项目

  1. 创建构建目录 :
    在项目根目录下创建一个名为build的子目录:
bash 复制代码
mkdir build
cd build
  1. 运行CMake配置 :
    在构建目录中运行CMake指令:
bash 复制代码
cmake ..

这将读取CMakeLists.txt并生成构建文件。

  1. 编译项目 :
    运行编译命令(例如使用make):
bash 复制代码
make
  1. 运行可执行文件 :
    编译完成后,可以在build目录中找到生成的可执行文件,运行它:
bash 复制代码
./MyQtApp

使用CMake构建Qt项目具有以下优势:

  1. 跨平台支持:CMake可以在不同的操作系统上生成相应的构建文件。
  2. 简化依赖管理:CMake可以更容易地管理项目依赖。
  3. 更好的集成:与现代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

重新构建项目,生成的可执行文件以及窗口的图标就会换成设置的图标。

相关推荐
扶尔魔ocy1 小时前
【qt openGL入门笔记】坐标系统和摄像机
qt·opengl
C++ 老炮儿的技术栈15 小时前
main函数之后的调用
c语言·c++·人工智能·qt·mfc·c
沫璃染墨20 小时前
《Qt从零入门系列(十二):Qt文件操作详解——从QFile读写到QFileInfo与记事本实战》
开发语言·网络·c++·qt·交互·信号处理·文件
时间的拾荒人21 小时前
Qt 界面布局与容器控件详解:从分组框到布局管理器
开发语言·qt·面试
王铭诗1 天前
QT界面安装
qt
程序员老陆1 天前
嵌入式 Qt:QWidgets 还是 QML / Qt Quick?
开发语言·qt
待什么青丝1 天前
【外设】之大彩串口显示屏
单片机·qt·显示器
Frank_refuel1 天前
深入理解RpcRouter(远端调用模块)
开发语言·qt
Quz2 天前
QML 分隔线:Rectangle、菜单与工具栏分隔线用法
qt
Quz2 天前
QML PathView 入门:直线路径与曲线路径
qt