重学Qt——GUI程序设计

GUI程序设计

GUI程序构建

QT程序构建原理

Qt项目构建过程基本原理

  • 元对象系统和MOC
  • UI文件和UIC
  • 资源文件和RCC

元对象系统和MOC

  • 元对象系统
    • Qt的元对象系统提供了运行时类型信息和信号/槽机制,允许对象之间的动态交互。
    • 提供了一项重要功能,允许开发者在运行时获取类的信息,如属性、方法等。
  • MOC(Meta-Object Compiler)
    • MOC是Qt工具链的一部分,用于解析Qt特定的C++代码,生成元对象代码。
    • MOC处理含有特定宏(如QObjectQ_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 指定项目的配置选项,如debugreleasestaticlib等。
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

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

相关推荐
草莓熊Lotso3 小时前
Python 入门必吃透:函数、列表与元组核心用法(附实战案例)
大数据·服务器·开发语言·c++·人工智能·python·qt
茉莉玫瑰花茶13 小时前
Qt 信号与槽 [ 1 ]
开发语言·数据库·qt
十五年专注C++开发16 小时前
浅谈LLVM
开发语言·c++·qt·clang·llvm
小短腿的代码世界16 小时前
Qt数据库编程深度解析:从SQL基础到ORM架构设计
数据库·sql·qt
CSCN新手听安17 小时前
【Qt】Qt窗口(六)QMessageBox消息对话框的使用
开发语言·c++·qt
爱看书的小沐17 小时前
【小沐学WebGIS】基于Cesium.JS与jsbsim联动三维飞行仿真(OpenGL、Cesium.js、Three.js)
c++·qt·three.js·opengl·cesium·jsbsim
咸鱼翻身小阿橙21 小时前
Qt QML调用C++注册类
java·c++·qt
CSCN新手听安1 天前
【Qt】Qt窗口(五)QDialog对话框的使用,点击按钮弹出新的对话框,自定义对话框界面,模态对话框model
开发语言·c++·qt
羽翼未丰的啊博1 天前
Can_Chart上位机
网络·qt·汽车