奇牛Qt01 Qt概述 —— 奇牛+gemini
奇牛Qt01 Qt概述 —— 奇牛+gemini
1. 第一个 Qt 项目:注册信息交互
1.1 UI 界面设计
在 mainwindow.ui 文件中,通过拖拽控件实现如下简单的注册界面:
-
使用
QLabel显示文本标签(姓名、年龄、职业)。 -
使用
QLineEdit作为单行文本输入框,接收用户输入(分别命名为lineEditName、lineEditJob等)。 -
使用
QPushButton作为触发按钮(命名为pushButton)。
1.2 槽函数核心逻辑
void MainWindow::on_pushButton_clicked() {
// 获取输入框内容并拼接字符串
QString ret = "亲爱的 " + ui->lineEditName->text() + " " + ui->lineEditJob->text() + ",欢迎学习Qt!";
// 弹出标准信息提示框
QMessageBox::information(this, "WELCOME", ret, QMessageBox::Ok);
}
2. 项目源码深度分析
2.1 Qt核心类继承体系
Qt 的核心类体系基于多重继承与清晰的职责划分:
QObject (所有Qt对象的祖先,支持信号槽) QPaintDevice (所有可绘制对象的祖先)
\ /
\ /
v v
QWidget (所有用户界面组件的基类)
|
v
QMainWindow (主窗口类)
|
v
用户自定义窗口类 (如 MainWindow)
QObject:所有 Qt 对象的祖先。若一个类需要使用“信号与槽机制”,则必须继承自QObject并在类内声明Q_OBJECT宏。QPaintDevice:所有可绘制对象的祖先类,提供底层绘图设备支持。QWidget:所有用户界面组件(Widgets)的祖先类。QMainWindow:标准主窗体类,拥有预定义的完整标准窗口布局:- Menu Bar(菜单栏) / Toolbars(工具栏)
- Central Widget(核心主中心组件)
- Dock Widgets(可以在主窗体内浮动或停靠的停靠窗口)
- Status Bar(状态栏)
2.2 事件循环机制(exec())
在 main.cpp 中,最后通常会调用 return a.exec();。
-
作用:使程序进入主事件循环(Main Event Loop),使主线程处于等待操作系统事件(如鼠标点击、键盘输入、重绘等)的状态。
-
工作流:
操作系统/底层事件 -> 压入事件队列 -> 事件循环(Event Loop)分发 -> 分发给对应对象的
event()函数进行事件处理。
2.3 项目组织文件(.pro)解析
.pro 文件是 Qt 项目的管理配置文件,决定了 qmake 如何生成 Makefile:
QT += core gui # 包含 Qt 的核心模块(core)和界面模块(gui)
# 如果 Qt 主版本号大于 4,则需要显式引入 widgets 模块
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11 # 启用 C++11 标准支持
# 定义编译宏选项:当使用过时的 Qt API 时,编译器会抛出警告
DEFINES += QT_DEPRECATED_WARNINGS
# 项目包含的源文件
SOURCES += \
main.cpp \
mainwindow.cpp
# 项目包含的头文件
HEADERS += \
mainwindow.h
# 项目包含的 UI 设计文件
FORMS += \
mainwindow.ui
2.4 Qt 的核心宏定义与界面双重架构
2.4.1 头文件结构与源码解析 (mainwindow.h)
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
// 1. 命名空间宏与前置声明
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
// 2. 逻辑类定义
class MainWindow : public QMainWindow
{
Q_OBJECT // 3. 元对象宏
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui; // 4. 界面类实例指针
};
#endif // MAINWINDOW_H
Ui::MainWindow *ui是类MainWindow的成员变量
关键要点:
宏的引入与展开逻辑
QT_BEGIN_NAMESPACE 与 QT_END_NAMESPACE:
为了防止符号污染,Qt 允许将自定义或系统的类包裹在特定的 Qt 命名空间中。经由预处理器处理后,形如:
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
在编译时会展开为:
// 含义:在命名空间 QT_NAMESPACE 内部,还有一个叫 Ui 的命名空间,而在这个 Ui 里面,有一个叫 MainWindow 的类
namespace QT_NAMESPACE {
namespace Ui { class MainWindow; }
}
2.4.2 双重类架构设计 (Pimpl 模式)
在 Qt 架构中,一个窗体通常由两个同名但处于不同命名空间的 MainWindow 类协同工作,以实现“业务逻辑”与“物理界面”的强解耦。
Ui::MainWindow(界面描述类):- 来源: 由 Qt 界面编译器(UIC)根据
.ui描述文件自动生成,存储于ui_mainwindow.h中。 - 职责: 属于纯粹的界面描述层,内部仅包含界面控件的指针(如按钮、文本框)与布局初始化逻辑(
setupUi)。
- 来源: 由 Qt 界面编译器(UIC)根据
MainWindow(业务逻辑类):- 来源: 由开发者手动编写,对应
mainwindow.h与mainwindow.cpp。 - 职责: 负责处理核心业务逻辑、事件响应及信号槽连接。
- 来源: 由开发者手动编写,对应
解耦效益: 逻辑类通过“前置声明”引用界面类,无需在头文件中包含完整的
ui_mainwindow.h。一旦界面发生变动,仅需重新编译自动生成的界面类,而不会引发逻辑类头文件的级联编译,从而大幅提升大型项目的编译速度。
2.4.3 元对象核心:Q_OBJECT 宏
- 强制规范: 凡是继承自
QObject(或其子类如QMainWindow)的类,其类定义内部的第一行必须隐式包含Q_OBJECT宏(无论当前是否显式使用信号槽)。 - 编译机制: 加上该宏后,元对象编译器(MOC)会在预编译阶段扫描该头文件,并自动生成对应的
moc_mainwindow.cpp文件。 - 核心功能: 该宏是 Qt 核心特性的基石,负责使该类具备元对象特性,包括但不限于:
- 信号与槽机制(Signals & Slots)
- 运行时类型信息(RTTI)与反射机制
- 动态属性系统
2.5 .ui 文件的编译原理
- 在 Qt Creator 的设计器中编辑完界面后,保存为 XML 格式的
.ui文件(如mainwindow.ui)。 - 在构建项目(点击“小锤子”构建按钮)时,Qt 的
uic工具会自动将.ui文件转换为标准 C++ 头文件ui_mainwindow.h(保存在构建/debug目录下)。 ui_mainwindow.h中会自动生成一个名为Ui_MainWindow的类,你在界面中拖放的所有控件都会自动转换为该类的public成员。- 在自定义的
MainWindow构造函数中,通过初始化列表实例化该 UI 对象,并调用setupUi(this)方法完成所有界面控件的创建、层级绑定与初始化:
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) {
ui->setupUi(this); // 初始化并构建完整的界面结构
}

浙公网安备 33010602011771号