当前位置: 首页 > news >正文

Qt跨线程的槽函数执行

定义两个类:Receiver接收信号,等待2秒后执行。Sender发送信号触发Receiver槽函数的执行

class Receiver : public QObject {Q_OBJECT
public slots:void exec() {QThread::sleep(1);qDebug() << QThread::currentThreadId() << "receiver exec";}
};class Sender : public QObject {Q_OBJECT
public:void exec() {emit sig();qDebug() << QThread::currentThreadId() << "sender exec";}
signals:void sig();
};

1. moveToThread(),但是直接调用

将sender对象放入线程,但是显示调用sender对象的exec()方法,此时moveToThread不起作用,receiver和sender都在主线程中执行,sender发送信号时,会等待receiver的槽函数执行完毕才执行后续的输出

int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);Receiver* r = new Receiver();Sender* s = new Sender();QObject::connect(s, SIGNAL(sig()), r, SLOT(exec()));QThread* thread = new QThread();s->moveToThread(thread);thread->start();s->exec();QThread::sleep(1000);return a.exec();
}

2. 槽函数在子线程中执行

将receiver放到单独的线程中,sender在主线程中发信号触发receiver的槽函数。此时默认槽函数连接方式Qt::AutoConnection等同于Qt::QueuedConnection,槽函数在子线程中执行,sender发送信号后立刻执行输出语句

额外的:

  1. 子线程必须通过start()开启,否则receiver
  2. 如果指定槽函数的连接方式为Qt::DirectConnection,槽函数也会在主线程中执行
int main() {Receiver* r = new Receiver();Sender* s = new Sender();QObject::connect(s, SIGNAL(sig()), r, SLOT(exec()));QThread* thread = new QThread();r->moveToThread(thread);thread->start();s->exec();QThread::sleep(1000);
}

3. 信号循环发送,但槽函数执行速度慢

将Sender类的exec()函数改为循环执行5次,发送5次信号会直接执行完成。Receiver中的槽函数正常执行5次,执行过程不会被新来的信号打断

class Sender : public QObject {Q_OBJECT
public:void exec() {for (int i = 0; i < 5; i++) {emit sig();qDebug() << QThread::currentThreadId() << "sender exec";}}
signals:void sig();
};

在这里插入图片描述

4. 一次触发两个槽函数

Sender中一次发送两个信号,分别触发Receiver中的两个槽函数,一个延迟1s执行一个立即执行。槽函数按照发送信号的顺序执行。

class Sender : public QObject {Q_OBJECT
public:void exec() {for (int i = 0; i < 5; i++) {emit sig();emit sig2();qDebug() << QThread::currentThreadId() << "sender exec";}}
signals:void sig();void sig2();
};class Receiver : public QObject {Q_OBJECT
public slots:void exec() {QThread::sleep(1);qDebug() << QDateTime::currentDateTime() << QThread::currentThreadId() << "receiver exec";}void exec2() {qDebug() << QDateTime::currentDateTime() << QThread::currentThreadId() << "receiver exec2";}
};

在这里插入图片描述
总结: 在Qt::QueuedConnection连接模式下,跨线程的槽函数调用会按照信号发送顺序执行。槽函数执行过程中不会被中断,槽函数执行完毕后再次开始事件循环,继续执行下一次的槽函数。来不及执行的信号和参数会被框架“保存”起来

相关文章:

  • CGAL的3D Alpha Shapes
  • 阿里推荐 LongAdder ,不推荐 AtomicLong !
  • Qt使用ffmpeg获取视频文件封面图
  • Idea小技巧
  • 【密码学引论】密码协议
  • 【LeetCode】151. 反转字符串中的单词(StringBuilder类)
  • Amazon CodeWhisperer 在 vscode 的应用
  • 全球移动通信(2G/3G/4G/5G)频谱分布情况
  • 程序员的50大JVM面试问题及答案
  • 【笔记】网络流算法模板
  • CSS3新增样式
  • Gitlab仓库推送到Gitee仓库的一种思路
  • 腾讯云debian服务器的连接与初始化
  • 基于Java (spring-boot)的宠物管理系统
  • 【运维面试100问】(九)了解Raid嘛?
  • 【挥舞JS】JS实现继承,封装一个extends方法
  • Android Volley源码解析
  • C++类中的特殊成员函数
  • CEF与代理
  • CSS选择器——伪元素选择器之处理父元素高度及外边距溢出
  • ES6 学习笔记(一)let,const和解构赋值
  • ES学习笔记(12)--Symbol
  • GDB 调试 Mysql 实战(三)优先队列排序算法中的行记录长度统计是怎么来的(上)...
  • HTTP中GET与POST的区别 99%的错误认识
  • Javascript 原型链
  • JAVA之继承和多态
  • js递归,无限分级树形折叠菜单
  • Redis 懒删除(lazy free)简史
  • session共享问题解决方案
  • springboot_database项目介绍
  • ------- 计算机网络基础
  • 聊聊springcloud的EurekaClientAutoConfiguration
  • 使用 Docker 部署 Spring Boot项目
  • 使用 Xcode 的 Target 区分开发和生产环境
  • 算法---两个栈实现一个队列
  • 通信类
  • 推荐一款sublime text 3 支持JSX和es201x 代码格式化的插件
  • 学习HTTP相关知识笔记
  • 国内唯一,阿里云入选全球区块链云服务报告,领先AWS、Google ...
  • ​2021半年盘点,不想你错过的重磅新书
  • ​LeetCode解法汇总2182. 构造限制重复的字符串
  • #在线报价接单​再坚持一下 明天是真的周六.出现货 实单来谈
  • (70min)字节暑假实习二面(已挂)
  • (LeetCode C++)盛最多水的容器
  • (翻译)terry crowley: 写给程序员
  • (仿QQ聊天消息列表加载)wp7 listbox 列表项逐一加载的一种实现方式,以及加入渐显动画...
  • (附源码)springboot码头作业管理系统 毕业设计 341654
  • (附源码)ssm教师工作量核算统计系统 毕业设计 162307
  • (三)uboot源码分析
  • (学习日记)2024.04.10:UCOSIII第三十八节:事件实验
  • (已解决)什么是vue导航守卫
  • (原創) 如何將struct塞進vector? (C/C++) (STL)
  • .NET : 在VS2008中计算代码度量值
  • .NET CORE 2.0发布后没有 VIEWS视图页面文件
  • .net中我喜欢的两种验证码