QT学习笔记(2):剖析QT代码的组成

0 阅读4分钟

image.png

main.cpp

写C++代码,都会有一个mian函数,QT代码也不例外,是完全一样的,位于main.cpp内:

image.png 这个代码会先包含#include "mainwindow.h",这个mainwindow.h就是自动生成的主界面的mainwindow类的头文件。

在mian函数内,会创建一个QApplication a的类对象,这个QT的类,然后创建我们窗口界面类MainWindow w,并让其w.show()显示出来,其实就是打开界面。

然后return a.exec();,这个代码其实就是会一直执行QApplication的exec函数,这个函数内其实会有一个事件循环,它会卡在这里一直检测事件直到你点击了界面的X关闭按钮,这也是我们界面show之后能一直显示的原因。

mainwindow.cpp

image.png

image.png #include "mainwindow.h":引入当前类的头文件,里面定义了 MainWindow 类的声明。

  • #include "ui_mainwindow.h":Qt 工具自动生成的头文件,包含 UI 界面的类定义(Ui::MainWindow)。
  • #include :引入 Qt 的 QLabel 控件头文件,用于显示文本 / 图片。

image.png 第 5 行:构造函数声明

  • MainWindow::MainWindow(QWidget* parent)
  • MainWindow:::作用域解析运算符,表示这是 MainWindow 类的构造函数。
  • (QWidget* parent):接收一个 QWidget* 类型的父窗口指针,这是 Qt 父子对象机制的标准写法,用于内存管理和窗口层级。

第 6-7 行:构造函数初始化列表

  • : QMainWindow(parent):调用父类 QMainWindow 的构造函数,把 parent 传递给父类,完成窗口基础初始化。

  • , ui(new Ui::MainWindow):初始化成员变量 ui,在堆上创建 Ui::MainWindow 对象,并把指针赋值给 ui。

  • 用初始化列表比在函数体内 ui = new ... 效率更高,还能初始化 const/ 引用成员。

第 9 行:初始化 UI

  • ui->setupUi(...):调用 Qt 生成的 setupUi 函数,自动创建 UI 文件里定义的所有控件,并把它们挂载到 this(当前 MainWindow 实例)上。

  • ->:指针成员访问运算符,ui 是指针,所以用 -> 调用它的成员函数。

第 10 行:创建标签控件

  • QLabel* label:声明一个 QLabel 类型的指针变量 label。

  • new QLabel("Hello QT!", this):在堆上创建一个 QLabel 对象,文本内容为 "Hello QT!",并把 this(当前窗口)设为它的父对象。

  • Qt 中,父对象会自动管理子控件的内存,父对象销毁时子对象会自动释放。

第 11 行:设置中心控件

  • setCentralWidget(...) 是 QMainWindow 的成员函数,用于设置窗口的中心控件(占据窗口主体区域的控件)。

  • 这里把刚才创建的 label 设置为中心控件,窗口就会显示这个标签了。

image.png 第 14 行:析构函数声明

  • ~ 表示这是析构函数,在对象被销毁时自动调用,用于释放资源。

第 16 行:释放 UI 对象

  • delete 用于释放堆上分配的内存。
  • 这里释放 ui 指向的 Ui::MainWindow 对象,避免内存泄漏。
  • 注意:Qt 中 new 的子控件如果设置了父对象,会被父对象自动释放,但 ui 是我们手动 new 的,没有父对象,所以必须手动 delete。

mainwindow.h

image.png 首先是#ifndef MAINWINDOW_H、#define MAINWINDOW_H,我们写头文件时经常用到,其实是防止头文件重复包含的。

image.png 然后是上面的一个命名空间的包含,这个是我们写C++时没有遇到的,这个是QT所特有的,当我们有mainwindow.h、mainwindow.cpp、mainwindow.ui这三个文件时,当我们进行编译构建时,QT会根据mainwindow.ui,给我们生成一个中间文件,叫ui_mainwindow.h,这个头文件里面会在命名空间Ui内生成一个和我们界面类名同名的MainWindow类,只不过是在Ui命名空间内。

这个Ui::MainWindow,继承自Ui_MainWindow类。 然后我们头文件这里的代码,则是声明这个Ui::MainWindow类。

image.png 声明了这个类之后,我们在MainWindow类private内,声明了Ui::MainWindow *ui;这个指针,这个类指针就是我们在.cpp文件内进行控件访问的对象指针。

在头文件类声明的开头有一个Q_OBJECT,这个也是QT自带的,如果你自己定义了一个类,想用qt的信号槽功能、动态属性、翻译功能这些QT独有的功能,就需要带这个宏。

这个宏其实展开是一段QT的moc元对象声明代码,元对象代码本质就是用于反射的,C++没有反射功能,但QT通过它的元对象系统,实现了反射,进而实现了信号槽这些C++本身不支持的功能

.pro项目文件

每个Qt项目都有一个 .pro(项目)文件,它由 qmake 工具处理,用于生成最终的Makefile。理解它是配置项目的基础。

打开 CVProcessDemo.pro 文件,它看起来是这样的:

image.png

  • QT += core gui:

指定项目需要链接的Qt模块。core 是核心模块(信号槽、容器等),gui 是图形用户界面基础模块。widgets 是传统的UI控件模块,因为Qt版本大于4,所以被自动添加。

  • CONFIG += c++17:

指定项目使用的C++标准。这是您作为C++程序员需要关注的关键配置。

  • SOURCES、HEADERS、FORMS:

    分别列出了项目中的所有源文件(.cpp)、头文件(.h)和界面文件(.ui)。当您添加新文件时,需要手动或通过Qt Creator的菜单将其添加到相应变量中。