news 2026/3/11 10:41:20

10.信号和槽connect函数

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
10.信号和槽connect函数

先明确核心:Qt信号槽连接的核心函数

Qt中最常用、最易理解的connect重载形式(Qt5及以上推荐):

QMetaObject::Connection QObject::connect( const QObject *sender, // 参数1:发送者 PointerToMemberFunction signal, // 参数2:发送者的信号 const QObject *receiver, // 参数3:接收者 PointerToMemberFunction method, // 参数4:接收者的槽函数/信号 Qt::ConnectionType type = Qt::AutoConnection // 参数5:连接类型(可选) );

下面逐参数拆解,每个参数都配“含义+要求+示例”,新手能直接对应理解。


一、参数1:const QObject *sender(信号发送者)

核心含义

指向发出信号的QObject子类对象的指针(比如工作线程对象、按钮对象、自定义Worker对象)。

关键要求
  1. 必须是QObject或其子类(如QPushButtonQThread、自定义AdcWorker);
  2. 不能是nullptr(空指针),否则连接失败且运行时报警;
  3. 发送者对象的生命周期需大于连接的生命周期(避免野指针)。
示例
// 发送者:自定义的ADC工作对象(继承QObject) AdcWorker *worker = new AdcWorker(); // 发送者:Qt内置的按钮对象 QPushButton *btn = new QPushButton("开始采集");

二、参数2:PointerToMemberFunction signal(要发送的信号)

核心含义

发送者对象的信号函数指针,格式为&类名::信号名(Qt5新语法,推荐)。

关键要求
  1. 信号必须是发送者类中用signals:关键字声明的函数(无返回值、可重载);
  2. 信号函数只声明,不实现(Qt MOC工具自动生成实现);
  3. 语法必须是&类名::信号名(Qt4的字符串形式如"SIGNAL(newAdcData(AdcFrame))"已废弃);
  4. 信号的参数类型需与槽函数的参数类型兼容(可少不可多,后面会讲)。
示例
// 信号声明(在AdcWorker类中) class AdcWorker : public QObject { Q_OBJECT signals: // 信号:携带AdcFrame类型参数 void newAdcData(AdcFrame frame); // 无参数信号 void collectFinished(); }; // 参数2的正确写法:&类名::信号名 &AdcWorker::newAdcData &AdcWorker::collectFinished &QPushButton::clicked // Qt内置按钮的点击信号

三、参数3:const QObject *receiver(信号接收者)

核心含义

指向接收信号并执行槽函数的QObject子类对象的指针(比如主线程的窗口对象、控制器对象、另一个Worker对象)。

关键要求
  1. 和参数1一样,必须是QObject或其子类;
  2. 可以是nullptr(此时参数4需是lambda表达式,Qt会自动管理);
  3. 接收者对象销毁时,Qt会自动断开连接(避免悬空连接)。
示例
// 接收者:主线程的窗口对象(继承QMainWindow/QWidget) MainWindow *window = this; // 在窗口类中,this指向当前窗口对象 // 接收者:空指针(配合lambda使用) nullptr

四、参数4:PointerToMemberFunction method(要执行的槽函数/信号)

核心含义

接收者对象的槽函数/信号指针(或lambda表达式),是信号触发后实际执行的逻辑。

关键要求
场景1:绑定类的槽函数(传统方式)
  1. 槽函数需用public slots:/slots:/public:(Qt5后可不用slots关键字)声明;
  2. 槽函数的参数数量 ≤ 信号的参数数量,且对应位置的参数类型必须一致;
    • ✅ 合法:信号newAdcData(AdcFrame)→ 槽onNewData(AdcFrame)(参数数量/类型一致);
    • ✅ 合法:信号newAdcData(AdcFrame)→ 槽onNewData()(槽无参数,忽略信号参数);
    • ❌ 非法:信号newAdcData()→ 槽onNewData(AdcFrame)(槽参数比信号多);
  1. 语法:&类名::槽函数名
场景2:绑定lambda表达式(Qt5推荐,简洁)
  1. 无需声明槽函数,直接写匿名函数;
  2. lambda的参数列表需与信号参数匹配(可省略);
  3. 此时参数3可设为nullptr,或指向lambda中捕获的对象。
示例
// 场景1:绑定类的槽函数(MainWindow类中) class MainWindow : public QMainWindow { Q_OBJECT public slots: // 槽函数:参数与信号一致 void onNewAdcData(AdcFrame frame) { qDebug() << "收到数据:" << frame.value; } // 槽函数:无参数(忽略信号的参数) void onCollectFinished() { qDebug() << "采集完成"; } }; // 参数4的正确写法(绑定槽函数) &MainWindow::onNewAdcData &MainWindow::onCollectFinished // 场景2:绑定lambda表达式(参数3为nullptr) [](AdcFrame frame) { qDebug() << "Lambda接收数据:" << frame.value; } []() { qDebug() << "采集完成(Lambda)"; }

五、参数5:Qt::ConnectionType type(连接类型,可选)

核心含义

指定信号和槽的执行方式(线程间如何传递信号),默认值为Qt::AutoConnection(推荐新手用默认)。

常用类型(新手只需掌握前3个)

连接类型

核心含义

适用场景

Qt::AutoConnection(默认)

自动判断:
1. 发送者和接收者同线程 → 直接调用;
2. 不同线程 → 队列调用

绝大多数场景(新手优先用)

Qt::DirectConnection

直接调用:信号发出时,槽函数立即在发送者线程执行

同线程、需同步执行的场景(如UI按钮点击)

Qt::QueuedConnection

队列调用:信号放入接收者线程的事件队列,接收者线程空闲时执行

跨线程(如工作线程→主线程),避免阻塞发送者

Qt::BlockingQueuedConnection

阻塞队列调用:信号发出后,发送者线程阻塞,直到槽函数执行完成

需等待槽函数执行结果的跨线程场景(慎用,易死锁)

Qt::UniqueConnection

附加标记:确保连接唯一(重复调用connect不会创建多个连接)

避免多次点击按钮导致槽函数执行多次

示例
// 默认连接(AutoConnection) connect(worker, &AdcWorker::newAdcData, window, &MainWindow::onNewAdcData); // 跨线程强制队列调用(QueuedConnection) connect(worker, &AdcWorker::newAdcData, window, &MainWindow::onNewAdcData, Qt::QueuedConnection); // 唯一连接(避免重复连接) connect(worker, &AdcWorker::collectFinished, window, &MainWindow::onCollectFinished, Qt::UniqueConnection);

二、完整实战示例(所有参数对应)

// 1. 定义发送者和接收者 AdcWorker *worker = new AdcWorker(); // 参数1:sender MainWindow *window = this; // 参数3:receiver // 2. 完整的connect调用(所有参数对应) QMetaObject::Connection conn = connect( worker, // 参数1:信号发送者(AdcWorker对象) &AdcWorker::newAdcData, // 参数2:发送的信号(带AdcFrame参数) window, // 参数3:信号接收者(主窗口对象) &MainWindow::onNewAdcData, // 参数4:执行的槽函数(参数匹配) Qt::QueuedConnection // 参数5:跨线程队列调用 ); // 3. 绑定lambda的简化写法(参数3为nullptr) connect( worker, &AdcWorker::collectFinished, nullptr, // 参数3:空指针 []() { qDebug() << "采集完成(Lambda)"; }, // 参数4:lambda表达式 Qt::UniqueConnection // 参数5:唯一连接 );

总结(核心参数要点)

  1. 参数1/3:必须是QObject子类对象指针,决定“谁发信号”和“谁收信号”;
  2. 参数2:发送者的信号指针(&类名::信号名),无返回值、只声明不实现;
  3. 参数4:接收者的槽函数/lambda,参数数量≤信号、类型需匹配;
  4. 参数5:连接类型(默认Auto即可),跨线程优先QueuedConnection,避免重复连接加UniqueConnection。

新手记住:connect(发信号的对象, &类::信号, 收信号的对象, &类::槽, 连接类型),按这个模板写,99%的场景都不会错。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/10 9:08:39

MGWR多尺度地理加权回归终极指南:从入门到精通

MGWR多尺度地理加权回归终极指南&#xff1a;从入门到精通 【免费下载链接】mgwr 项目地址: https://gitcode.com/gh_mirrors/mg/mgwr 您是否曾为传统空间分析方法无法捕捉复杂的局部关系而苦恼&#xff1f;&#x1f914; 多尺度地理加权回归&#xff08;MGWR&#xff…

作者头像 李华
网站建设 2026/3/9 15:10:02

HunyuanVideo-Foley TensorRT加速:NVIDIA GPU极致优化

HunyuanVideo-Foley TensorRT加速&#xff1a;NVIDIA GPU极致优化 1. 引言&#xff1a;视频音效生成的智能化革命 1.1 行业背景与技术痛点 在影视、短视频和游戏内容创作中&#xff0c;音效是提升沉浸感的关键一环。传统音效制作依赖人工逐帧匹配环境声、动作声等&#xff0…

作者头像 李华
网站建设 2026/3/10 18:27:45

AI人脸隐私卫士容灾备份:异常断电恢复机制设计

AI人脸隐私卫士容灾备份&#xff1a;异常断电恢复机制设计 1. 引言&#xff1a;AI 人脸隐私卫士的工程挑战与容灾需求 随着个人数据安全意识的提升&#xff0c;本地化、离线运行的隐私保护工具正成为用户刚需。AI 人脸隐私卫士基于 Google MediaPipe 的高精度人脸检测模型&am…

作者头像 李华
网站建设 2026/3/7 8:01:08

远程医疗康复指导:低延迟骨骼点云端传输方案实测

远程医疗康复指导&#xff1a;低延迟骨骼点云端传输方案实测 1. 什么是骨骼点数据传输&#xff1f; 骨骼点数据传输是远程医疗康复系统的核心技术之一。简单来说&#xff0c;就是通过摄像头捕捉患者的肢体动作后&#xff0c;AI算法会识别出人体关键关节位置&#xff08;如肩膀…

作者头像 李华
网站建设 2026/3/8 18:45:03

Pytorch关键点检测训练代码:云端GPU即开即用,1元起跑

Pytorch关键点检测训练代码&#xff1a;云端GPU即开即用&#xff0c;1元起跑 引言 作为一名算法工程师&#xff0c;你是否也遇到过这样的困境&#xff1a;面试前需要复现关键点检测项目&#xff0c;但家里的电脑跑不动ResNet这样的复杂模型&#xff0c;用谷歌Colab又总是断连…

作者头像 李华
网站建设 2026/3/8 22:21:08

GLM-4.6V-Flash-WEB显存优化:8GB GPU运行实战案例

GLM-4.6V-Flash-WEB显存优化&#xff1a;8GB GPU运行实战案例 &#x1f4a1; 获取更多AI镜像 想探索更多AI镜像和应用场景&#xff1f;访问 CSDN星图镜像广场&#xff0c;提供丰富的预置镜像&#xff0c;覆盖大模型推理、图像生成、视频生成、模型微调等多个领域&#xff0c;支…

作者头像 李华