第一个 Qt 程序
本节将带你创建第一个 Qt 应用程序,了解 Qt 项目的基本结构和工作原理。
创建项目
使用 Qt Creator
- 打开 Qt Creator,选择"文件" → "新建文件或项目"
- 选择"Application (Qt)" → "Qt Widgets Application"
- 设置项目名称(如
FirstApp)和保存路径 - 构建系统选择 CMake(现代 Qt 项目的标准选择)
- 类信息页面保持默认(基类为
QMainWindow) - 完成创建
项目结构解析
创建完成后,你会看到以下文件结构:
FirstApp/
├── CMakeLists.txt # CMake 构建配置
├── main.cpp # 程序入口点
├── mainwindow.h # 主窗口类声明
├── mainwindow.cpp # 主窗口类实现
└── mainwindow.ui # UI 设计文件(XML)
让我们逐一了解这些文件的作用。
程序入口 main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
// 1. 创建 QApplication 对象
// 每个 Qt GUI 程序必须有且只有一个 QApplication
// 它管理应用程序的全局资源、事件循环等
QApplication app(argc, argv);
// 2. 创建主窗口对象
MainWindow window;
// 3. 显示窗口
window.show();
// 4. 进入事件循环
// exec() 会阻塞,直到应用程序退出
// 它不断处理用户输入、定时器、网络事件等
return app.exec();
}
代码解读
QApplication 是 Qt 应用程序的核心类:
- 管理应用程序的全局设置
- 处理事件循环(Event Loop)
- 管理字体、光标、剪贴板等全局资源
- 解析命令行参数
Qt 是基于事件驱动的框架。exec() 启动的事件循环不断从系统获取事件(鼠标点击、键盘输入、定时器等),并分发给相应的对象处理。没有事件循环,GUI 就无法响应用户操作。
主窗口类
mainwindow.h(头文件)
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow> // Qt 主窗口基类
// 前向声明 UI 类
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
// 继承自 QMainWindow
class MainWindow : public QMainWindow
{
// 宏:启用 Qt 的元对象系统
// 提供信号槽、运行时类型信息等特性
Q_OBJECT
public:
// 构造函数,parent 用于指定父窗口
MainWindow(QWidget *parent = nullptr);
// 析构函数
~MainWindow();
private:
// UI 类指针,用于访问界面元素
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
关键概念解释
Q_OBJECT 宏:
这是 Qt 的核心宏,必须在所有使用信号槽、属性系统或需要运行时类型信息的类声明中添加。它会在编译时生成额外的元对象代码(moc 处理)。
父对象系统:
Qt 使用对象树管理内存。当创建对象时传入 parent 参数:
- 父对象销毁时会自动销毁所有子对象
- 子对象无需手动 delete
- 这是 Qt 自动内存管理的基础
mainwindow.cpp(实现文件)
#include "mainwindow.h"
#include "ui_mainwindow.h" // 由 .ui 文件生成的头文件
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent) // 调用基类构造函数
, ui(new Ui::MainWindow) // 创建 UI 对象
{
// 设置 UI
// 这会创建所有在 Designer 中设计的控件
ui->setupUi(this);
// TODO: 在这里添加自定义初始化代码
}
MainWindow::~MainWindow()
{
// 释放 UI 对象
delete ui;
}
UI 设计文件
mainwindow.ui 是一个 XML 文件,描述界面布局。Qt Creator 提供可视化编辑器(Qt Designer)来编辑它。
在 Designer 中添加控件
- 双击
mainwindow.ui打开设计器 - 从左侧控件面板拖拽控件到窗口:
- 拖一个
Label(标签)到中央区域 - 拖一个
Push Button(按钮)到标签下方
- 拖一个
- 在右侧属性面板修改控件属性:
- Label 的 text 改为 "Hello, Qt!"
- Button 的 text 改为 "Click Me"
- 按
Ctrl+S保存
理解 UI 文件
虽然可以用可视化工具编辑,但了解 UI 文件的结构很有帮助:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<widget class="QWidget" name="centralwidget">
<widget class="QLabel" name="label">
<property name="text">
<string>Hello, Qt!</string>
</property>
</widget>
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>Click Me</string>
</property>
</widget>
</widget>
</widget>
</ui>
编译时,uic(UI Compiler)会将这个 XML 转换为 C++ 头文件 ui_mainwindow.h。
添加交互功能
让我们为按钮添加点击事件处理。
方式一:使用信号槽(推荐)
在 mainwindow.h 中添加槽函数声明:
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots: // 槽函数声明区域
void onButtonClicked();
private:
Ui::MainWindow *ui;
};
在 mainwindow.cpp 中实现并连接:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox> // 消息框
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 连接信号和槽
// 当按钮被点击时,调用 onButtonClicked 函数
connect(ui->pushButton, &QPushButton::clicked,
this, &MainWindow::onButtonClicked);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::onButtonClicked()
{
// 显示消息框
QMessageBox::information(this, "消息", "Hello, Qt!");
}
方式二:自动连接(命名约定)
Qt 支持按命名约定自动连接信号槽。将槽函数命名为 on_<控件名>_<信号名>:
private slots:
void on_pushButton_clicked(); // 自动连接
然后在构造函数中不需要手动 connect,Qt 会自动找到并连接这个槽函数。
自动连接功能需要在 setupUi 之后调用 QMetaObject::connectSlotsByName(this),而 setupUi 内部已经调用了这个函数,所以直接使用命名约定即可。但要注意命名必须完全匹配(区分大小写)。
CMakeLists.txt 解析
cmake_minimum_required(VERSION 3.16)
project(FirstApp VERSION 1.0 LANGUAGES CXX)
# C++ 标准设置
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Qt 特有的设置
set(CMAKE_AUTOMOC ON) # 自动处理 moc(元对象编译器)
set(CMAKE_AUTORCC ON) # 自动处理资源文件
set(CMAKE_AUTOUIC ON) # 自动处理 UI 文件
# 查找 Qt 包
find_package(Qt6 REQUIRED COMPONENTS
Core # 核心非 GUI 功能
Gui # GUI 基础功能
Widgets # 桌面控件
)
# 创建可执行文件
add_executable(FirstApp
main.cpp
mainwindow.cpp
mainwindow.h
mainwindow.ui
)
# 链接 Qt 库
target_link_libraries(FirstApp PRIVATE
Qt6::Core
Qt6::Gui
Qt6::Widgets
)
关键设置说明
| 设置 | 说明 |
|---|---|
CMAKE_AUTOMOC ON | 自动扫描头文件中的 Q_OBJECT 宏,运行 moc 生成元对象代码 |
CMAKE_AUTOUIC ON | 自动将 .ui 文件编译为 C++ 头文件 |
CMAKE_AUTORCC ON | 自动将资源文件(.qrc)编译进可执行文件 |
运行程序
在 Qt Creator 中
点击左下角的绿色运行按钮,或按 Ctrl+R。
命令行方式
# 创建构建目录
mkdir build && cd build
# 配置
cmake ..
# 编译
cmake --build .
# 运行(Linux/macOS)
./FirstApp
# 运行(Windows)
FirstApp.exe
练习
-
修改窗口标题:在构造函数中使用
setWindowTitle("我的第一个 Qt 程序") -
调整窗口大小:使用
resize(800, 600)设置窗口尺寸 -
添加更多控件:
- 添加一个
QLineEdit(输入框) - 点击按钮时,将输入框的内容显示在消息框中
提示代码:
void MainWindow::onButtonClicked()
{
QString text = ui->lineEdit->text(); // 获取输入框文本
QMessageBox::information(this, "输入内容", text);
} - 添加一个
-
使用布局:在 Designer 中将控件放入
QVBoxLayout(垂直布局),使窗口缩放时控件自动调整位置
下一步
现在你已经了解了 Qt 程序的基本结构。接下来学习 Qt 核心概念,深入理解信号槽机制、元对象系统和事件循环。