Qt信号发送过快,槽函数处理不过来解决方法

2023-11-17

问题:
跨线程使用信号与槽连接,信号的发送时间间隔小于槽函数处理的时间间隔,造成的问题。

子线程下的槽函数,用sleep来模拟槽函数的耗时操作:

void MyThread::myTimeout()
{
    qDebug() << "test";
    QThread::sleep(2);
}

主线程下的信号发送函数,通过点击按钮来发送信号:

void Widget::on_buttonStart_clicked()
{
    emit startThread();
}

线程之间的信号连接函数:

    connect(this, &Widget::startThread, myT, &MyThread::myTimeout);

现象:在我们连续点击按钮后,能明显看到打印的信息有延时。

分析:在我们跨线程使用信号与槽时,connect函数默认是使用Qt::QueuedConnection队列的传输方式。当我们的槽函数处理不过来时,会先将传输的信号存入队列中,等槽函数处理完了再拿出来。

解决方法:
我们需要在等槽函数执行完后,才能发送新的信号。

方法一:使用connect的第五个参数,设置为Qt::BlockingQueuedConnection

槽函数的调用时机与Qt::QueuedConnection一致,不过发送完信号后发送者所在线程会阻塞,直到槽函数运行完。接收者和发送者绝对不能在一个线程,否则程序会死锁。在多线程间需要同步的场合可能需要这个。

    connect(this, &Widget::startThread, myT, &MyThread::myTimeout,Qt::BlockingQueuedConnection);

这个也是可以的,但是当我们子线程,处理所需时间很长时,
主线程会出现明显的卡顿,效果不太好。

方法二:
使用bool QObject::blockSignals(bool block)函数屏蔽信号发送,当槽函数处理完后,再开启。

子线程下的改动:

void MyThread::myTimeout()
{
    qDebug() << "test";
    QThread::sleep(2);
    emit recover();
}

主线程下的改动:

void Widget::on_recover()
{
    ui->buttonStart->blockSignals(false);
}

void Widget::on_buttonStart_clicked()
{
    emit startThread();
    ui->buttonStart->blockSignals(true);
}

增加信号连接函数:

    connect(this, &Widget::startThread, myT, &MyThread::myTimeout);
    connect(myT, &MyThread::recover, this, &Widget::on_recover);

通过增加对信号发送的限制,这样的话可以实现,只有在槽函数处理完成后,才会开始发送信号。

但是用这个函数有一个问题就是,这个对象的所有信号,在屏蔽的期间都不会发送了,也需要等槽函数处理完之后才能发送信号,实验代码如下。

void Widget::on_buttonStart_clicked()
{
    emit startThread();
    ui->buttonStart->blockSignals(true);
}

void Widget::on_buttonStart_pressed()
{
    qDebug() << "信号能正常触发";
}

所以如果说两个对象之间只是一对一的信号连接的话,可以使用blockSignals函数

1、屏蔽信号的方式还可以用:

void MyThread::myTimeout()
{
    QObject::sender()->blockSignals(true);
    QThread::sleep(2);
    QObject::sender()->blockSignals(false);
}

这样的话就可以直接在槽函数里,实现将发送信号的对象屏蔽和恢复。

先记录一下,后面有更好的方法再补充。。。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Qt信号发送过快,槽函数处理不过来解决方法 的相关文章

随机推荐

  • 数据结构--二叉树的顺序结构及实现

    文章目录 前言 堆 堆的概念以及结构 堆的搭建 堆的实现 前言 普通的二叉树是不适合用数组来存储的 因为这样会存在大量的空间浪费 但是完全二叉树却更适合用顺序结构存储 堆 堆的概念以及结构 堆的概念 堆是一种二叉树 可以用顺序结构的数组来存
  • TCP协议为什么是三次握手而不是两次

    1 主要是为了防止已经失效的连接请求报文突然有传送到了服务器 从而导致不必要的错误和资源的浪费 2 两次握手只能保证单项连接时通常的 因为TCP是一个双向传输协议 只有经过第三次握手 才能确保双向都可以接收到对方发送的数据
  • 【经典】markdown编辑器手册

    这里写自定义目录标题 欢迎使用Markdown编辑器 新的改变 功能快捷键 合理的创建标题 有助于目录的生成 如何改变文本的样式 插入链接与图片 如何插入一段漂亮的代码片 生成一个适合你的列表 创建一个表格 设定内容居中 居左 居右 Sma
  • ubuntu 查看端口占用命令

    查看端口占用情况 netstat nultp
  • Android开发中访问服务器常用到的response.getStatusCode()的值各代表什么

    response getStatusCode 200 代表请求成功 response getStatusCode 303 代表重定向 response getStatusCode 400 代表请求错误 response getStatusC
  • 访问方法access method---单表访问方法(三十六)

    上篇文章回忆了innodDB的独立表空间和系统表空间的结构 因为需要梳理的知识点太多 所以额外用一篇 独立表空间 系统表空间总结 innoDB表空间 三十五 单表的访问方法 对我们开发来说 mysql就是个软件 用sql查询我们需要的数据
  • 基于布谷鸟算法结合灰狼算法求解最优目标

    基于布谷鸟算法结合灰狼算法求解最优目标 在本文中 我们将介绍如何使用布谷鸟算法和灰狼算法的组合来求解最优目标问题 我们将提供相应的MATLAB代码 以便读者可以直接实现和测试这种算法组合的效果 布谷鸟算法 Cuckoo Search Alg
  • 使用Git Bash从Git上下载代码到本地以及上传代码到码云Git

    前提是已经安装了GitBash 这个稍后再出教程 1 新建一个目录 存放下载下来的项目 我在D盘新建了一个 gitspace 文件夹 用来存放下载下来的项目 2 进入刚刚新建的文件夹 即进入 gitspace 点击鼠标右键 选择 Git B
  • 2021年国家平均工资出炉,你又被平均了吗?

    近期 国家统计局发布2021全国平均薪资 IT业年平均工资突破20万位于榜首 分行业门类看 IT行业年平均工资私营 非私营均位列第一 年平均工资最高的3个行业分别是信息传输 软件和信息技术服务业201506元 科学研究和技术服务业15177
  • Django基础入门⑧:Django路由详细讲解

    Django基础入门 Django路由 Django路由 路由分发函数 反向解析 反向解析应用 使用url标签实现反向解析 reverse 函数实现反向解析 reverse 函数简析 命名空间namespace 个人简介 以山河作礼 Pyt
  • mysql常用日期时间/数值函数

    author skate time 2013 05 16 1 日期时间函数 时间转化秒函数 time to sec mysql gt select time to sec 01 01 01 time to sec 01 01 01 3661
  • 将数组以逗号拼接_javascript将数组拼接成一个字符串

    这里记录下在JavaScript中如何将数组拼接成一个字符串 所谓的将数组拼接成一个字符串 意思就是将数组中的元素逐个拼接到一个字符串中 并加以特定的分隔符 在JavaScript中可以有两种方式 一种是Array对象提供的join 方法
  • Mysql-表关系多对多设计

    多对多 如 订单 和 商品 一个商品对应多个订单 一个订单包含多个商品 实现方式 建立第三张中间表 中间表至少包含两个外键 分别关联两方主键 DROP TABLE tb order DROP TABLE tb goods DROP TABL
  • C++ 引用

    引用变量是一个别名 也就是说 它是某个已存在变量的另一个名字 一旦把引用初始化为某个变量 就可以使用该引用名称或变量名称来指向变量 引用和指针 引用很容易与指针混淆 它们之间有三个主要的不同 不存在空引用 引用必须连接到一块合法的内存 一旦
  • MinGW-w64下载文件失败the file has been downloaded incorrectly

    文章目录 前言 必读 1 问题背景 2 报错原因 3 解决方案 前言 必读 笔者强烈推荐使用 linux平台 搭建C 环境所需的东西 如果是用windows平台 则会出现很多小问题 或者即使安装好了 程序跑起来的时候仍会有问题 如果是单纯想
  • The Raft Group [naming_instance_metadata] did not find the Leader node;caused: The Raft Group

    1 异常信息 caused errCode 500 errMsg do metadata operation failed caused com alibaba nacos consistency exception Consistency
  • 安装MySQL(无管理员权限)

    Install MySQL without administrator permission Step 1 Download https cdn mysql com Downloads MySQL 5 7 mysql 5 7 24 win3
  • “echo 0 > /proc/sys/kernel/hung_task_timeout_secs“ disables this message

    现象 主机无缘无故死机 主机上服务无响应 日志出现大量 echo 0 gt proc sys kernel hung task timeout secs disables this message 日志输出信息 分析 echo 0 gt p
  • Future异步

    Future异步是Java中常用的异步编程方式之一 它能够在代码执行过程中返回一个代表未来结果的Future对象 使得程序能够在等待结果的同时继续执行其他操作 本文将从Future异步的定义 使用方法和优缺点等方面对其进行详细介绍 一 Fu
  • Qt信号发送过快,槽函数处理不过来解决方法

    问题 跨线程使用信号与槽连接 信号的发送时间间隔小于槽函数处理的时间间隔 造成的问题 子线程下的槽函数 用sleep来模拟槽函数的耗时操作 void MyThread myTimeout qDebug lt lt test QThread