560 字
1 分钟
【QT】信号槽与事件
信号与槽
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 所在线程)中执行,通常用 QueuedConnection 或 AutoConnection。
一对多、多对一、断开
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)**体系:键盘、鼠标、绘制、定时器、自定义事件等。
事件传播顺序(简要)
QApplication::notify()分发- 目标对象的
event()— 可统一过滤或转发 - 具体处理函数如
mousePressEvent()、keyPressEvent()、paintEvent() - 未处理可调用基类实现或
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 即可。
分享
如果这篇文章对你有帮助,欢迎分享给更多人!
部分信息可能已经过时
相关文章 智能推荐
1
【QT】布局与QSS
StudyNotes 介绍 QHBoxLayout 等布局管理、QSS 选择器语法及与 QPalette、QStyle 的关系。
2
【QT】交叉编译与部署
StudyNotes 以 NXP i.MX 为例说明交叉工具链配置、Qt Creator Kits 及嵌入式板端部署要点。
3
【QT】入门与构建
StudyNotes 介绍 Qt 事件循环、链接库、qmake/CMake 构建及 MOC/UIC/RCC 编译流程与跨平台原理。
4
【QT】核心类型与容器
StudyNotes 介绍 QObject 对象树、QString、顺序与关联容器及迭代遍历方式。
5
【QT】对话框与常用控件
StudyNotes 涵盖 QFileDialog、QMessageBox 等标准对话框及按钮、输入、视图等常用控件分类。
