Qt 是一套跨平台的 C++ 应用程序开发库。与 MFC 不同,Qt 支持 Windows、Linux、macOS 甚至嵌入式平台。
环境搭建
安装
1 2 3 4 5 6
| sudo apt-get install qt5-default qttools5-dev-tools designer
sudo pip3 install pyqt5
|
CLion 不能打开 .ui 文件,需要借助 Qt Designer。两者可以同时部署给同一个项目——把 build 文件夹设为同一个,共同读取 CMakeLists.txt。
项目结构
1 2 3 4 5 6 7
| project/ ├── Sources/ # .cpp 源文件 │ └── main.cpp ├── Headers/ # .h 头文件 ├── Forms/ # .ui 界面文件 ├── lib/ # 第三方库 .dll/.a └── include/ # 第三方库头文件
|
开发目录不要含中文路径。
Qt 对标准 C++ 进行了扩展,通过元对象编译器(MOC)将 Qt 特性代码转化为标准 C++ 后再编译。
三个基础
QObject 是所有使用元对象系统的类的基类
- 在类的
private 部分声明 Q_OBJECT 宏
- MOC 为每个 QObject 子类生成必要代码
动态类型转换
1 2 3 4 5 6 7 8 9 10
| QObject → QWidget → QMyWidget
QObject *obj = new QMyWidget;
QWidget *w = qobject_cast<QWidget*>(obj);
timer->inherits("QTimer");
|
信号与槽
信号与槽是 Qt 最核心的通信机制,优势在于松散耦合——发送者和接收者通过 connect 连接,彼此不依赖。
基本用法
1 2 3 4 5
| QObject::connect(sender, SIGNAL(clicked()), receiver, SLOT(onClicked()));
connect(sender, &QPushButton::clicked, receiver, &MyClass::onClicked);
|
- 一个信号可以连接多个槽
- 多个信号可以连接同一个槽
- 信号和槽的参数类型必须匹配
Lambda 表达式
Lambda 用于封装短小的匿名函数,在 Qt 中常作为槽函数使用。
语法
1
| [capture](params) mutable -> return_type { body }
|
| 部分 |
说明 |
[] |
捕获列表,Lambda 引出符 |
() |
参数列表(可省略) |
mutable |
取消 const 限制(可省略) |
-> type |
返回类型(可省略,编译器推导) |
{} |
函数体 |
捕获列表
1 2 3 4 5 6
| [] [var] [&var] [=] [&] [=, &var]
|
Qt 中的典型用法
1 2 3
| connect(btn, &QPushButton::clicked, this, [this]() { label->setText("Button clicked!"); });
|
Lambda 本质是编译器生成一个匿名类的匿名对象,重载了 operator()。
对象树与内存管理
Qt 的对象呈树状结构。关键规则:设置父对象后,父对象销毁时会自动释放所有子对象。
1 2 3 4 5 6
| QPushButton *btn = new QPushButton(this); btn->move(100, 200);
QPushButton *btn = new QPushButton; btn->setParent(this);
|
窗口坐标
1 2 3 4 5
| resize(800, 600); setFixedSize(400, 300); setWindowTitle("My Window"); btn->move(x, y); btn->setGeometry(100, 300, w, h);
|
CMakeLists.txt 配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| cmake_minimum_required(VERSION 3.5) project(MyQtApp)
set(CMAKE_CXX_STANDARD 17) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON)
find_package(Qt5 REQUIRED COMPONENTS Widgets)
add_executable(${PROJECT_NAME} main.cpp mainwindow.cpp )
target_link_libraries(${PROJECT_NAME} Qt5::Widgets)
|