news 2026/4/23 11:21:11

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/4/17 21:49:51

UV Squares终极指南:快速掌握Blender UV网格重塑技巧

UV Squares终极指南&#xff1a;快速掌握Blender UV网格重塑技巧 【免费下载链接】UvSquares Blender addon for reshaping UV selection into grid. 项目地址: https://gitcode.com/gh_mirrors/uv/UvSquares 想要在Blender中轻松解决UV展开难题吗&#xff1f;UV Square…

作者头像 李华
网站建设 2026/4/18 7:12:59

错过这次再等一年:自定义集合表达式扩展全网最深解析

第一章&#xff1a;错过这次再等一年&#xff1a;自定义集合表达式扩展全网最深解析在现代编程语言设计中&#xff0c;集合操作的灵活性直接决定了开发效率与代码可读性。自定义集合表达式扩展通过引入用户可定义的语法糖&#xff0c;使开发者能够以声明式方式操作数据集合&…

作者头像 李华
网站建设 2026/4/20 2:00:48

AI手势识别显存不足?纯CPU版免依赖部署解决方案

AI手势识别显存不足&#xff1f;纯CPU版免依赖部署解决方案 1. 引言&#xff1a;AI 手势识别与追踪的现实挑战 随着人机交互技术的快速发展&#xff0c;AI手势识别正逐步从实验室走向消费级应用&#xff0c;广泛应用于虚拟现实、智能驾驶、远程控制和无障碍交互等场景。然而&…

作者头像 李华
网站建设 2026/4/13 16:35:49

联想刃7000k BIOS完全解锁教程:5步开启隐藏高级功能

联想刃7000k BIOS完全解锁教程&#xff1a;5步开启隐藏高级功能 【免费下载链接】Lenovo-7000k-Unlock-BIOS Lenovo联想刃7000k2021-3060版解锁BIOS隐藏选项并提升为Admin权限 项目地址: https://gitcode.com/gh_mirrors/le/Lenovo-7000k-Unlock-BIOS 联想刃7000k作为一…

作者头像 李华
网站建设 2026/4/4 11:04:31

抖音下载神器:从零开始掌握高效内容采集技巧

抖音下载神器&#xff1a;从零开始掌握高效内容采集技巧 【免费下载链接】douyin-downloader 项目地址: https://gitcode.com/GitHub_Trending/do/douyin-downloader 还在为找不到合适的抖音内容管理工具而苦恼吗&#xff1f;这款功能强大的抖音下载工具将彻底改变你的…

作者头像 李华
网站建设 2026/4/17 2:31:53

多尺度地理加权回归终极指南:如何精准分析空间异质性数据

多尺度地理加权回归终极指南&#xff1a;如何精准分析空间异质性数据 【免费下载链接】mgwr 项目地址: https://gitcode.com/gh_mirrors/mg/mgwr 想要突破传统空间分析方法的局限吗&#xff1f;多尺度地理加权回归(MGWR)作为空间统计领域的革命性技术&#xff0c;正在重…

作者头像 李华