一、先搞懂:信号与槽到底是什么?
可以把它理解成 **"事件通知 + 响应" 的万能连接方式 **:
- 信号(Signal) :某个对象发生了特定事件时,发出的 "通知"。比如按钮被点击(
clicked())、滑块被拖动(valueChanged())、窗口关闭(close()),都是信号。 - 槽(Slot):接收信号并执行的 "响应函数"。比如按钮点击后要执行 "弹出提示框""保存数据",这些逻辑写在槽函数里。
- 核心逻辑 :用 Qt 的
connect()函数把 "信号" 和 "槽" 连起来,当信号发出时,对应的槽函数会自动执行 ------ 不用手动调用函数,实现了对象之间的 "解耦"(按钮不用知道点了之后要做什么,只负责发信号就行)。
二、新手能看懂的代码示例(最基础的按钮点击)
先看一段完整代码,实现 "点击按钮,弹出提示框",核心就是信号与槽的连接:
cpp
运行
#include <QApplication>
#include <QPushButton>
#include <QMessageBox>
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
// 1. 创建一个按钮对象(信号发送者)
QPushButton btn("点击我");
btn.resize(200, 50);
btn.show();
// 2. 定义槽函数(响应逻辑):弹出提示框
auto showMsg = [&]() {
QMessageBox::information(&btn, "提示", "你点击了按钮!");
};
// 3. 核心:连接信号与槽
// 格式:connect(信号发送者, 发送的信号, 信号接收者, 要执行的槽函数)
QObject::connect(&btn, &QPushButton::clicked, &app, showMsg);
return app.exec(); // 启动应用事件循环
}
关键代码解释:
&QPushButton::clicked:按钮被点击时发出的内置信号(Qt 自带的控件都有大量现成信号);showMsg:我们自定义的槽函数(可以是普通函数、lambda 表达式、类成员函数);connect():把 "按钮点击信号" 和 "弹出提示框的槽函数" 绑定,点击按钮就自动执行showMsg。
三、信号与槽的核心特点
- 松耦合:发送信号的对象(按钮)和接收信号的对象(执行槽函数的对象)互不依赖,改槽函数逻辑不用动按钮代码,维护超方便;
- 多对多连接:一个信号可以连多个槽(点击按钮同时弹出提示 + 保存数据),一个槽也可以接收多个信号(按钮 1、按钮 2 点击都执行同一个保存函数);
- 类型安全:Qt 会检查信号和槽的参数类型是否匹配,参数不对应编译时会报错,避免运行时 bug;
- 支持自定义:除了 Qt 控件自带的信号,你可以给自定义类添加专属信号(比如 "数据加载完成" 信号),也能自定义槽函数响应。
四、新手常见用法(两种主流方式)
方式 1:Qt 5/6 通用的新式连接(推荐)
就是上面示例的写法,清晰且类型安全:
cpp
运行
// 自定义类的信号与槽示例
class MyWidget : public QWidget {
Q_OBJECT // 必须加这个宏,否则信号槽失效
public:
MyWidget(QWidget *parent = nullptr) : QWidget(parent) {
QPushButton *btn = new QPushButton("自定义信号", this);
// 连接按钮点击信号到自定义槽
connect(btn, &QPushButton::clicked, this, &MyWidget::mySlot);
}
signals: // 声明自定义信号(只声明,不用实现)
void mySignal(QString msg);
public slots: // 声明槽函数(Qt6中槽可以是普通成员函数,不用加slots关键字)
void mySlot() {
emit mySignal("槽函数被触发了"); // 发送自定义信号
qDebug() << "按钮点击后的响应";
}
};
Q_OBJECT宏:必须加在自定义类的开头,Qt 会通过这个宏生成信号槽的底层代码;emit:发送自定义信号的关键字,比如emit mySignal("消息")就是主动发出信号;- Qt6 简化:槽函数不用再放在
public slots里,普通成员函数、lambda 都能当槽。
方式 2:Qt Designer 可视化连接(新手更易上手)
不用写connect()代码,拖控件时直接绑定:
- 打开 Qt Designer,拖一个按钮到界面;
- 右键按钮→"转到槽"→选择
clicked()信号; - Qt 会自动生成槽函数的框架,你只需要在里面写响应逻辑即可。
总结
- 信号与槽是 Qt 实现界面交互、对象通信的核心机制,核心是 "事件通知 + 响应";
- 关键是用
connect()绑定 "信号发送者 + 信号" 和 "接收者 + 槽函数",Qt6 支持更简洁的写法; - 新手入门优先学 "新式连接 + lambda 表达式",或用 Qt Designer 可视化绑定,降低上手难度。