奇牛Qt01 Qt概述 —— 奇牛+gemini

奇牛Qt01 Qt概述 —— 奇牛+gemini

1. 第一个 Qt 项目:注册信息交互

1.1 UI 界面设计

mainwindow.ui 文件中,通过拖拽控件实现如下简单的注册界面:

  • 使用 QLabel 显示文本标签(姓名、年龄、职业)。

  • 使用 QLineEdit 作为单行文本输入框,接收用户输入(分别命名为 lineEditNamelineEditJob 等)。

  • 使用 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_NAMESPACEQT_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)。
  • MainWindow(业务逻辑类):
    • 来源: 由开发者手动编写,对应 mainwindow.hmainwindow.cpp
    • 职责: 负责处理核心业务逻辑、事件响应及信号槽连接。

解耦效益: 逻辑类通过“前置声明”引用界面类,无需在头文件中包含完整的 ui_mainwindow.h。一旦界面发生变动,仅需重新编译自动生成的界面类,而不会引发逻辑类头文件的级联编译,从而大幅提升大型项目的编译速度。

2.4.3 元对象核心:Q_OBJECT

  • 强制规范: 凡是继承自 QObject(或其子类如 QMainWindow)的类,其类定义内部的第一行必须隐式包含 Q_OBJECT 宏(无论当前是否显式使用信号槽)。
  • 编译机制: 加上该宏后,元对象编译器(MOC)会在预编译阶段扫描该头文件,并自动生成对应的 moc_mainwindow.cpp 文件。
  • 核心功能: 该宏是 Qt 核心特性的基石,负责使该类具备元对象特性,包括但不限于:
    • 信号与槽机制(Signals & Slots)
    • 运行时类型信息(RTTI)与反射机制
    • 动态属性系统

2.5 .ui 文件的编译原理

  1. 在 Qt Creator 的设计器中编辑完界面后,保存为 XML 格式的 .ui 文件(如 mainwindow.ui)。
  2. 在构建项目(点击“小锤子”构建按钮)时,Qt 的 uic 工具会自动将 .ui 文件转换为标准 C++ 头文件 ui_mainwindow.h(保存在构建/debug目录下)。
  3. ui_mainwindow.h 中会自动生成一个名为 Ui_MainWindow 的类,你在界面中拖放的所有控件都会自动转换为该类的 public 成员。
  4. 在自定义的 MainWindow 构造函数中,通过初始化列表实例化该 UI 对象,并调用 setupUi(this) 方法完成所有界面控件的创建、层级绑定与初始化:
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) {
    ui->setupUi(this); // 初始化并构建完整的界面结构
}
posted @ 2026-07-06 20:28  学习笔记草稿存放账号  阅读(6)  评论(0)    收藏  举报