QT信号槽的在不同线程或者在同一线程下的连接方式

2023-10-29

最近使用一个QTreeWidget加载数据库数据然后以tree的方式展现出来。
于是在读取数据库的时候新建一个线程的来读取数据库,读取数据完毕之后,再树形控件上显示出来。
新建线程的目的是为了防止读取大数据的时候出现界面阻塞的情况,提供用户体验。然后数据读取完毕之后,是不能在工作线程中把读取到的数据显示出来的,
必须传到主界面上显示出来。只是就会使用信号槽的方式把读取的数据传到主界面。

信号槽的连接方式有以下几种:
Qt::AutoConnection - 自动关联,这是默认值。如果信号和槽函数在同一个线程(包括在同一主线程或者在同一工作线程)中,则使用Qt::DirectConnection方式,
如果信号和槽函数没有在同一个线程中,则使用Qt::QueuedConnection
在信号发送的时候,决定采用哪种关联类型。
Qt::DirectConnection - 直接关联。信号和槽函数在同一个线程中,发射完信号后立即调用槽函数,只用在槽函数执行完成返回后,发射信号后面的代码才可以执行,相当于阻塞模式,和MFC中的SendMessage相同
Qt::QueuedConnection - 队列关联。信号和槽函数不再同一个线程中,当发送信号的线程发送信号后立即执行下面的代码,发送的信号会放到另一个线程的信号队列中等待获取执行,相当于不阻塞模式,和MFC中的PostMessage相同
Qt::BlockingQueuedConnection - 阻塞队列关联。信号和槽不再同一个线程中,发送信号的线程发送一个信号后,这个线程不会执行下面的代码,直到接收信号的线程中的槽函数执行完成返回后才会继续执行。
如果采用这种连接方式的信号和槽函数在同一个线程中,则会形成死锁。
Qt::UniqueConnection - 唯一关联。主要使信号发送者和接受者有唯一的连接。防止多次调用connect形成重复关联。一旦形成重复关联,信号一个旦发射,就会有对应的槽函数多次执行。

##1.信号和槽函数在同一个线程中的情况

class Test: public QMainWindow
{
    Q_OBJECT
Test()
signals:
	void sigFirst();
private slots:
	void slotFirst();
}

Test::Test(QWidget *parent)
: QMainWindow(parent) {
	ui.setupUi(this);
	for (int i = 0; i < 5; i++) {//采用默认方式,连接5次
		connect(this, SIGNAL(sigFirst()), this, SLOT(slotFirst()));
	}
	
	emit sigFirst();
}


void Test::slotFirst() {
	numCoon++;
	qDebug() << QStringLiteral("信号第")<<numCoon<<QStringLiteral("次连接");
}

运行之后的输出内容:

"信号第" 1 "次连接"
"信号第" 2 "次连接"
"信号第" 3 "次连接"
"信号第" 4 "次连接"
"信号第" 5 "次连接"`

如果代码修改一下,改为:

connect(this, SIGNAL(sigFirst()), this, SLOT(slotFirst()), Qt::UniqueConnection);//注意第五个参数

再次运行一下,查看输出:

"信号第" 1 "次连接"

这次只发送了一次信号,但是咱们连接了5次,所以采用Qt::UniqueConnection方式连接,无论连接多少次,只发送一次信号,也只会执行一次槽函数

##2.信号和槽函数在不同线程中的情况
自定义线程类:

#pragma once

#include <QThread>

class QtTestThread : public QThread {
	Q_OBJECT

public:
	QtTestThread(QObject *parent);
	~QtTestThread();
protected:
	void run();
signals:
	void sigSecond();
};

#include "QtTestThread.h"
#include <QDebug>

QtTestThread::QtTestThread(QObject *parent)
: QThread(parent) {
}

QtTestThread::~QtTestThread() {
}

void QtTestThread::run() {
	emit sigSecond();
	qDebug() << QStringLiteral("信号发送完毕!");
}

调用线程类:

class QtTestThread;
class Test: public QMainWindow
{
    Q_OBJECT
Test()
signals:
	void sigFirst();
private slots:
	void slotThread();
private:
	QtTestThread* testThread;
}

#include "QtTestThread.h"
Test::Test(QWidget *parent)
: QMainWindow(parent) {
	ui.setupUi(this);
	
	testThread = new QtTestThread(this);
	connect(testThread, SIGNAL(sigSecond()), this, SLOT(slotThread()));//没有第五个参数,也就是采用默认的连接方式

	testThread->start();
}

void Test::slotThread() {
	qDebug() << QStringLiteral("线程发送的信号-槽函数执行!");
	QThread::sleep(3);
}

运行一下,输出内容:

"信号发送完毕!"
"线程发送的信号-槽函数执行!"

由此可以看出,信号发送完成信号后,就直接运行下面的代码了,而发送的信号就会被放到主线程的信号队列中等待执行。

咱们信号槽的连接方式修改一下,添加信号槽的连接方式 Qt::BlockingQueuedConnection:

connect(testThread, SIGNAL(sigSecond()), this, SLOT(slotThread()), Qt::BlockingQueuedConnection);

再次运行一下:

"线程发送的信号-槽函数执行!"
"信号发送完毕!"//时间等待3秒之后才输出这句话

采用Qt::BlockingQueuedConnection的连接方式就实现了信号和槽函数的同步执行。
以上!

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

QT信号槽的在不同线程或者在同一线程下的连接方式 的相关文章

  • QT“找不到 Qt 平台插件“xcb””

    我出于学术原因安装了QT everywhere 5 15开源版 但无法运行程序 首先 我编译了必要的源文件make并安装了QT Creator 然后我选择qmake来运行其中的程序 当我尝试运行示例程序时 遇到以下错误 qt qpa plu
  • Qt 信号槽,新符号中的转换类型[重复]

    这个问题在这里已经有答案了 鉴于以下两个 connect ui gt comboBox SIGNAL activated QString ps SLOT requestPlotsAvailable QString connect ui gt
  • 检查目录是否为空

    我正在尝试检查目录是否为空 MainWindow MainWindow QWidget parent QMainWindow parent ui new Ui MainWindow ui gt setupUi this QDir Dir h
  • 获取小部件的背景颜色 - 真的

    我无法获取小部件的实际背景颜色 在我的特殊情况下 我在使用 QTabWidget 中的小部件时遇到问题 这是在Windows7上 因此 经典的小部件有一些灰色背景 而选项卡内的小部件通常用白色背景绘制 I tried def bgcolor
  • Windows 消息循环而不是 QApplication::exec() / QApplication::processEvents()

    我是否想念任何一个Qt如果我替换功能QApplication exec 使用标准 Windows 消息循环实现 这应该可以澄清我的意思 运行事件处理的常用 Qt 方式 int main int argc char argv QApplica
  • Qt GUI 编程设计

    我正在尝试创建一个 GUI 应用程序 主窗口 一个QMainWindow 包含 9 个固定大小的标签以及主窗口的大小 我尝试在没有 Qt GUI Designer 的情况下以编程方式制作它 该项目构建时没有错误 但我看不到主窗口上显示的任何
  • 调整 QML 图像显示尺寸

    我有一个带有嵌套的 QML 窗口RowLayout 在内排我有两个图像 来源 png这些图像的文件 故意 相当大 当我尝试设置height这些图像上的属性使它们变小 但它们仍然被画得很大 Desired Appearance Actual
  • 安装多个版本的 Qt 库

    我在windows中安装了QtSDK 它的Qt库版本是4 7 0 现在我想为 mingw 和 VS2008 安装 Qt 库版本 4 8 2 我怎样才能做到这一点 如何向QtCreator引入多个版本 注意 我已经从以下位置下载了库http
  • 在 QtCreator 中将 OpenCV 2.3 与 Qt 结合使用

    随着 OpenCV 2 3 版本终于发布 我想在我的系统上编译并安装这个最新版本 由于我经常使用 Qt 和 QtCreator 我当然希望能够在我的 Qt 项目中使用它 我已经尝试了几种方法几个小时 但总是出现错误 第一次尝试 使用WITH
  • 从 QML 实例化 C++ 对象会产生巨大的内存使用开销

    实例化一个QObjectC 堆中的派生类为每个对象提供了大约 160 个字节 通过注册相同的对象qmlRegisterType 用于从 QML 创建并通过以下方式动态创建对象createObject 每个对象给我 2000 多个字节 这是完
  • Qt/c++ 随机字符串生成[重复]

    这个问题在这里已经有答案了 我正在创建一个应用程序 需要生成多个随机字符串 几乎就像一个由一定长度的 ASCII 字符组成的唯一 ID 这些字符混合有大写 小写 数字字符 有没有 Qt 库可以实现这一点 如果没有 在纯 C 中生成多个随机字
  • 如何在 C++ 和 QML 应用程序中使用 qrc?

    我在 Windows7 上用 c qnd Qt Creator QML 编写了 Qt Quick Desktop 应用程序 现在 我必须部署它 并且我需要隐藏 qml 文件和图像 意味着 将它们放入资源等中 我读到有一个很好的方法可以使用
  • 有没有办法在没有 QApplication::exec() 的情况下使用 Qt?

    有没有一种安全的方法可以在不调用 QApplication exec 的情况下使用 Qt 我有许多不同的对象正在对多个资源执行长期进程 至少其中一个正在与 Web 应用程序服务器进行通信 我正在制作一个 GUI 应用程序 提示用户在正确的时
  • 程序意外完成 - QT Creator

    我正在尝试使用 QT Creator 使用 QT 框架开发 GUI 控制台应用程序 我使用的是Windows XP 我安装了QT 4 8 3和mingw 两者均已安装 没有任何错误 然后我安装了QT Creator QT 版本 路径中的 Q
  • Qt Creator:如何区分 win32 和 win64

    我必须在 pro 文件中执行类似的操作 win32 LIBS L 3rdparty libusb win32 lib msvc llibusb else win64 LIBS L 3rdparty libusb win32 lib msvc
  • (如何)我可以抑制未找到包配置文件的警告吗?

    我正在尝试创建一个CMakeLists txt尝试查找的文件Qt5 如果失败 则尝试回退到Qt4安装 该脚本到目前为止有效 但如果出现以下情况我总会收到警告Qt5未安装 注意FindQt5 cmake是由提供Qt5并且仅当以下情况时才可用Q
  • GoQt 致命错误:QAbstractAnimation:没有这样的文件或目录

    我尝试编译 Qt 来开发桌面应用程序 我按照 Qt 网站上的官方 wiki 指南的说明进行操作 当我尝试go run示例文件夹中的示例 我收到错误 去运行 home pinkya rabbit workspace go1programs s
  • PyQt:如何设置组合框项目可检查?

    为了将 GUI 小部件数量保持在最低限度 我需要找到一种方法来为用户提供下拉菜单项的选择 这些菜单项可用于过滤掉 listWidget 项中显示的内容 假设 listWidget 列出了 5 个不同类别的项目 Cat A Cat B Cat
  • 加权 Voronoi 的 CGAL 2D APOLLONIUS 图 - 如何生成和获取面和顶点?

    我正在尝试根据阿波罗尼乌斯图生成加权沃罗诺伊 我正在使用 CGAL 库 我找不到如何从 apollonius 获取面和顶点的好例子 我有以下类型定义 typedef double NT typedef CGAL Cartesian lt N
  • 如何在 Qt 中以编程方式制作一条水平线

    我想弄清楚如何在 Qt 中制作一条水平线 这很容易在设计器中创建 但我想以编程方式创建一个 我已经做了一些谷歌搜索并查看了 ui 文件中的 xml 但无法弄清楚任何内容 ui 文件中的 xml 如下所示

随机推荐

  • 【微信小程序】微信小程序阻止IOS页面上下拖动问题

    为了阻止IOS端小程序页面上下拖动可以再对应的json文件当中添加这个配置 disableScroll true 参考链接 传送门
  • 基于CGAL、Qt5两层嵌套动态链接库的Cmake实现

    1 问题由来 因需要开发了一款基于CGAL的处理三维几何的子程序 简称子程序B 该子程序B被主程序A调用 我们知道CGAL还可以调用Qt5库用于图形显示 因此为了实现这一目标 设想利用Cmake制作一个可供主程序A调用的dll 此dll可调
  • Android BLE基础操作框架使用详解

    http www xiaoyaoyou1212 com 2016 08 28 Android BLE E5 9F BA E7 A1 80 E6 93 8D E4 BD 9C E6 A1 86 E6 9E B6 E4 BD BF E7 94
  • linux 安装mysql8.0.x

    MySQL MySQL简介 MySQL原本是一个开放源代码的关系数据库管理系统 原开发者为瑞典的MySQL AB公司 该公司于2008年被昇阳微系统 Sun Microsystems 收购 2009年 甲骨文公司 Oracle 收购昇阳微系
  • 电商订单状态【2】

    1 等待到款 如果您选择 网上支付 和 银行转账 这两种付款方式 当当在暂未收到您款项时 订单会显示 等待到款 建议您在订单保留期限内及时付款 2 等待预售商品到货 若您订购的商品为预售商品 商品到货前订单会显示 等待预售商品到货 3 正在
  • JVM系列(七) JVM 垃圾收集器

    我们知道JVM会回收垃圾 但是每种垃圾收集器的收集机制和收集的方法都不一样 今天我们讨论下几种垃圾回收机制 1 按照垃圾区域划分垃圾收集器 我们可以按照垃圾存在的区域来划分垃圾收集器 垃圾在堆内的区域分为 新生代垃圾 老年代垃圾 新生代老年
  • MySQL版本对应的驱动配置

    mysql驱动为8以上的版本 这时候需要在配置文件中设置为 spring datasource mysql数据库连接 type com zaxxer hikari HikariDataSource driver class name com
  • 最小生成树算法之Prim(普里姆)算法

    最小生成树的可以通过Kruskal 克鲁斯卡尔 算法或Prim 普里姆 算法求出 Prim算法基本介绍 Prim算法又称为 加点法 每次找出距离 此处的距离指的是距离最小生成树的距离 若此处无法理解 可直接跳过 看完下面例子就能理解 最小的
  • IDEA推送本地代码到新远程git地址

    步骤一 先用git创建一个远程项目路径 步骤二 利用IDEA 推送代码到本地仓库 然后在推送到远程git 1 创建本地git仓库 VCS gt Import into Version Control gt Create Git Reposi
  • Linux shell中2>&1的含义

    转载来源 Linux shell中2 gt 1的含义 作者 一个行走的民 https blog csdn net zhaominpro article details 82630528 1 和 2 在 Linux 中代表什么 在Linux系
  • LeetCode刷题-11

    数组 136 只出现一次的数字 题目描述 题目样例 Java方法 位运算 算法思路 代码 复杂度 题目描述 给定一个非空整数数组 除了某个元素只出现一次以外 其余每个元素均出现两次 找出那个只出现了一次的元素 题目样例 示例1 输入 2 2
  • CSS3 选择器 :nth-child 与 :nth-of-type 区别

    一 nth child 1 1 说明 nth child n 选择器匹配属于其父元素的第 N 个子元素 不论元素的类型 n 可以是数字 关键词或公式 注意 如果第 N 个子元素与选择的元素类型不同则样式无效 1 2 示例 div p 我是第
  • Linux 小游戏

    文章目录 1 banner 输出图形字符 2 xeyes 3 数字雨 4 aafire火焰效果 5 Space Invaders 太空侵略者 6 彩色火焰效果 1 banner 输出图形字符 先看效果 安装 sudo apt get upd
  • LA@向量组间的表示关系导出的向量组线性相关性@进阶@延伸组

    文章目录 延伸组 向量分量增减和相关性 短无关则长无关 长相关则短相关 从方程组解角度理解 推论 被表出向量组的线性相关性 用系数矩阵向量组的线性相关性讨论被表出向量组的相关性 归纳 被表出向量组线性相关性判定定理 被表示向量组和表出向量组
  • Numpy中的数组维度

    原文转载自我的博客benym cn 在对 np arange 24 0 1 2 3 23 进行重新的排列时 在多维数组的多个轴的方向上 先分配最后一个轴 对于二维数组 即先分配行的方向 对于三维数组即先分配平面的方向 代码 import n
  • Kubernetes 集群部署 ------ 二进制集群 (单 Master集群部署 + 多 Master群集部署)2

    基于上篇博客的部署的环境上 这篇博客开始部署 k8s集群中的 单 Master 群集 单 Master 集群架构图 以下是自签 SSL 证书列表 首先 我们要了解在 Master 上 要部署以下三大核心组件 kube apiserver 是
  • Vue 之 解决v-html生成的元素不能触发@click等vue事件和CSS样式不生效的方法

    一 简介 官方文档 通过上面官方文档的介绍我们可以得知两个重点 通过v html生成的页面元素 不会被当做Vue模板进行编译 只会作为普通的html代码被插入 也就是说通过v html插入的html代码中 如果包含vue的语法 例如 cli
  • 插入排序史上最经典的实现方式

    插入排序的原理 插入排序的代码实现 循环法 let arrayData 44 3 38 5 47 15 36 26 27 2 46 4 19 50 48 let insertSort arr gt 对于第0个元素 只有一个元素 所以没有比的
  • Gitlab服务器备份与还原

    文章目录 操作环境及相关指令 操作环境 相关指令 防火墙相关指令 端口号相关指令 Gitlab相关指令 文件传输 备份与还原 备份 Gitlab相关配置信息 还原 访问 操作环境及相关指令 操作环境 操作系统 root master cat
  • QT信号槽的在不同线程或者在同一线程下的连接方式

    最近使用一个QTreeWidget加载数据库数据然后以tree的方式展现出来 于是在读取数据库的时候新建一个线程的来读取数据库 读取数据完毕之后 再树形控件上显示出来 新建线程的目的是为了防止读取大数据的时候出现界面阻塞的情况 提供用户体验