560 字
1 分钟
【QT】信号槽与事件
2026-06-11

信号与槽#

Qt 的对象间通信机制:发送方信号与接收方关联后,信号发射时槽函数被调用(可跨线程,由连接类型决定)。

概念#

术语说明
信号(signal)在特定情况下发出的通知;在类声明的 signals: 区声明,只需原型,无需实现
槽(slot)对信号的响应函数;写在 public slots:private slots: 等;可与普通成员函数一样带参数

connect 写法#

Qt5/6 函数指针(推荐,编译期检查类型)

connect(sender, &Sender::valueChanged,
receiver, &Receiver::onValueChanged);
// 带参数自动匹配(参数类型须兼容)
connect(spinBox, QOverload<int>::of(&QSpinBox::valueChanged),
this, &MainWindow::onSpinChanged);

Lambda

connect(button, &QPushButton::clicked, this, [this]() {
ui->label->setText("clicked");
});

Qt4 字符串写法(不推荐,仅运行时检查)

connect(sender, SIGNAL(valueChanged(int)),
receiver, SLOT(onValueChanged(int)));

连接类型 Qt::ConnectionType#

类型行为
AutoConnection(默认)同线程直接调用;跨线程则队列到接收方线程
DirectConnection始终在发射线程同步调用槽
QueuedConnection事件入队,在接收方线程事件循环中异步执行
BlockingQueuedConnection跨线程时阻塞发射方直到槽执行完(同线程不可用)

跨线程更新 UI 时,槽应在主线程(QObject 所在线程)中执行,通常用 QueuedConnectionAutoConnection

一对多、多对一、断开#

connect(a, &A::sig, b, &B::slot1);
connect(a, &A::sig, c, &C::slot2); // 一对多
disconnect(a, &A::sig, b, &B::slot1); // 精确断开
disconnect(a, nullptr, nullptr, nullptr); // 断开 a 发出的所有连接

信号带参数、槽参数可更少#

信号参数类型须与槽兼容;槽可忽略多余参数。connect 会根据函数指针推导签名。

事件处理#

除信号槽外,Qt 还有**事件(QEvent)**体系:键盘、鼠标、绘制、定时器、自定义事件等。

事件传播顺序(简要)#

  1. QApplication::notify() 分发
  2. 目标对象的 event() — 可统一过滤或转发
  3. 具体处理函数如 mousePressEvent()keyPressEvent()paintEvent()
  4. 未处理可调用基类实现或 ignore()

重写事件处理函数#

void MyWidget::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton) {
// 处理
event->accept();
return;
}
QWidget::mousePressEvent(event); // 交给基类
}

eventFilter(事件过滤器)#

在一个对象上为另一个对象安装过滤器,在事件到达目标前拦截:

target->installEventFilter(this);
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
if (obj == target && event->type() == QEvent::KeyPress) {
// 处理或 return true 表示已消费
}
return QMainWindow::eventFilter(obj, event);
}

信号槽 vs 事件#

信号槽事件
方向明确的发布-订阅自顶向下分发
类型用户定义的语义QEvent 子类(类型枚举)
典型用途业务逻辑联动底层输入、绘制、窗口系统消息

定时器#

QTimer *timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, &MainWindow::onTimeout);
timer->start(1000); // 毫秒
// 单次
QTimer::singleShot(500, this, &MainWindow::delayedAction);

QObject::timerEvent() 配合 startTimer() 为底层 C 风格 API,一般用 QTimer 即可。

分享

如果这篇文章对你有帮助,欢迎分享给更多人!

【QT】信号槽与事件
https://lysj.work/posts/studynotes/qt/qt信号槽与事件/
作者
Sekiro
发布于
2026-06-11
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时

目录