(Qt) QThread 信号槽所在线程

文章目录

  • 💁🏻前言
  • 💁🏻Code
    • 💁🏻‍♂️Code
    • 💁🏻‍♂️环境
  • 💁🏻当前线程信号
    • 💁🏻‍♂️默认效果
    • 💁🏻‍♂️Qt::ConnectionType::AutoConnection
    • 💁🏻‍♂️Qt::ConnectionType::DirectConnection
    • 💁🏻‍♂️Qt::ConnectionType::QueuedConnection
  • 💁🏻外部线程的信号
    • 💁🏻‍♂️默认效果
    • 💁🏻‍♂️Qt::ConnectionType::AutoConnection
    • 💁🏻‍♂️Qt::ConnectionType::DirectConnection
    • 💁🏻‍♂️Qt::ConnectionType::QueuedConnection
  • 💁🏻END
    • 🌟关注我

💁🏻前言

在 Qt 中用一套自己的封装的多线程操作。

其中一种方式是继承 QThread 并实现 void run(); 方法使用 void start(); 启动,这是一种很常见的线程的封装方式。这种方式在 java 中也是这么设计的。

但是由于 Qt 的高度封装性和框架整体性,很多特性都是开发者自己测试出来的。

其中 QThread 配合信号槽的特性就是本文要观察的重点。

💁🏻Code

这里放一份基本的code,后面的观察都是基于具体 void QThread::run(); 的修改的观察。

本文下面默认的外部线程值得就是在 main() 中一致的线程。

💁🏻‍♂️Code

目录

C:.
└─mythreadmain.cppmythread.cppmythread.hmythread.pro

mythread.pro

QT = coreCONFIG += c++17 cmdlineSOURCES +=      \main.cpp    \mythread.cppHEADERS += \mythread.h

main.cpp

只负责创建我们观察的实例

#include <QCoreApplication>
#include <QDebug>
#include <QThread>#include "mythread.h"int main(int argc, char* argv[]) {QCoreApplication a(argc, argv);qDebug() << "Main Thread" << QThread::currentThread();MyThread myth;qDebug() << "Object-Thread" << myth.thread();return a.exec();
}

mythread.h

#ifndef MYTHREAD_H
#define MYTHREAD_H#include <QThread>class MyThread : public QThread {Q_OBJECT
public:explicit MyThread(QObject *parent = nullptr);protected:void run() override;signals:void signal_test();
};#endif  // MYTHREAD_H

mythread.cpp

在构造中就启动线程。(主要是想把所有操作都几种在一个文件中,不影响测试的效果个逻辑)

在槽函数的事件中,再次发出信号,查看连续的信号槽的效果。

#include "mythread.h"#include <QDebug>
#include <QThread>
#include <QTimer>MyThread::MyThread(QObject *parent) : QThread{parent} {qDebug() << QString("Construction-Line[%1]").arg(__LINE__) << QThread::currentThread();start();// QTimer::singleShot(100, this, [this]() { emit signal_test(); });
}void MyThread::run() {qDebug() << QString("Run-Line[%1]").arg(__LINE__) << QThread::currentThread();auto task = [this]() {qDebug() << QString(">>>Line[%1]").arg(__LINE__) << QThread::currentThread();QThread::sleep(1);emit signal_test();};connect(this, &MyThread::signal_test, task);// emit signal_test();qDebug() << QString("Run-Line[%1]").arg(__LINE__) << QThread::currentThread();exec();
}

当前模板下的测试样例效果:

由于这是一个不会自己终止的程序,因此下文中打印的效果仅截取关键部分表示示意。

Main Thread QThread(0x11072c8)
"Construction-Line[8]" QThread(0x11072c8)
Object-Thread QThread(0x11072c8)
"Run-Line[15]" MyThread(0x76fe70)
"Run-Line[27]" MyThread(0x76fe70)

💁🏻‍♂️环境

本文测试环境:Qt 5.15.2 MinGW 32-bit

下面放两个版本的 connect 的实现方式。

// 该 connect 的实现如下
connect(this, &MyThread::signal_test, task);// Qt 5.15.2
//connect to a functor
template <typename Func1, typename Func2>
static inline typename std::enable_if<QtPrivate::FunctionPointer<Func2>::ArgumentCount == -1, QMetaObject::Connection>::typeconnect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, Func2 slot)
{return connect(sender, signal, sender, std::move(slot), Qt::DirectConnection);
}// Qt 6.7.2
inline QMetaObject::Connection QObject::connect(const QObject *asender, const char *asignal,const char *amember, Qt::ConnectionType atype) const
{ return connect(asender, asignal, this, amember, atype); }

💁🏻当前线程信号

解开 void run(); 函数中的信号发送。

效果

根据不同的 connect,不只是最后一个连接类型 ConnectionType

槽函数可能在子线程,可能在主线程执行。

💁🏻‍♂️默认效果

void MyThread::run() {qDebug() << QString("Run-Line[%1]").arg(__LINE__) << QThread::currentThread();auto task = [this]() {qDebug() << QString(">>>Line[%1]").arg(__LINE__) << QThread::currentThread();QThread::sleep(1);emit signal_test();};connect(this, &MyThread::signal_test, task);emit signal_test();qDebug() << QString("Run-Line[%1]").arg(__LINE__) << QThread::currentThread();exec();
}
Main Thread QThread(0x12372c8)
"Construction-Line[8]" QThread(0x12372c8)
Object-Thread QThread(0x12372c8)
"Run-Line[15]" MyThread(0x76fe70)
">>>Line[18]" MyThread(0x76fe70)
">>>Line[18]" MyThread(0x76fe70)

效果

直接在当前线程中,发送信号,并默认的绑定 connect 是直接执行槽函数的,并槽函数执行线程是子线程。

并且由于在槽函数继续发送信号,导致下面的 qDebug() 没有打印。

💁🏻‍♂️Qt::ConnectionType::AutoConnection

connect(this, &MyThread::signal_test, QThread::currentThread(), task, Qt::ConnectionType::AutoConnection);
Main Thread QThread(0x11b72c8)
"Construction-Line[8]" QThread(0x11b72c8)
Object-Thread QThread(0x11b72c8)
"Run-Line[15]" MyThread(0x76fe70)
"Run-Line[27]" MyThread(0x76fe70)
">>>Line[18]" QThread(0x11b72c8)
">>>Line[18]" QThread(0x11b72c8)

效果

执行到 exec(), 槽函数在主线程执行。

效果同 Qt::ConnectionType::QueuedConnection

💁🏻‍♂️Qt::ConnectionType::DirectConnection

connect(this, &MyThread::signal_test, QThread::currentThread(), task, Qt::ConnectionType::DirectConnection);
Main Thread QThread(0x9372c8)
"Construction-Line[8]" QThread(0x9372c8)
Object-Thread QThread(0x9372c8)
"Run-Line[15]" MyThread(0x76fe70)
">>>Line[18]" MyThread(0x76fe70)
">>>Line[18]" MyThread(0x76fe70)

效果

在执行 exec() 前就触发槽函数。即槽函数在子线程中运行。

💁🏻‍♂️Qt::ConnectionType::QueuedConnection

connect(this, &MyThread::signal_test, QThread::currentThread(), task, Qt::ConnectionType::QueuedConnection);
Main Thread QThread(0x11e72c8)
"Construction-Line[8]" QThread(0x11e72c8)
Object-Thread QThread(0x11e72c8)
"Run-Line[15]" MyThread(0x76fe70)
"Run-Line[27]" MyThread(0x76fe70)
">>>Line[18]" QThread(0x11e72c8)
">>>Line[18]" QThread(0x11e72c8)

效果

执行到 exec(), 槽函数在主线程执行。

💁🏻外部线程的信号

在构造中直接启动线程,并在构造的线程中发送一个信号。

为什么要加一个定时器,因为要等待事件循环(Qt基础,不过多解释)。

MyThread::MyThread(QObject *parent) : QThread{parent} {qDebug() << QString("Construction-Line[%1]").arg(__LINE__) << QThread::currentThread();start();QTimer::singleShot(100, this, [this]() { emit signal_test(); });
}

效果

下方测试:均执行到 exec() 槽函数在主线程执行。

💁🏻‍♂️默认效果

void MyThread::run() {qDebug() << QString("Run-Line[%1]").arg(__LINE__) << QThread::currentThread();auto task = [this]() {qDebug() << QString(">>>Line[%1]").arg(__LINE__) << QThread::currentThread();QThread::sleep(1);emit signal_test();};connect(this, &MyThread::signal_test, task);// emit signal_test();qDebug() << QString("Run-Line[%1]").arg(__LINE__) << QThread::currentThread();exec();
}
Main Thread QThread(0xa772c8)
"Construction-Line[8]" QThread(0xa772c8)
Object-Thread QThread(0xa772c8)
"Run-Line[15]" MyThread(0x76fe70)
"Run-Line[27]" MyThread(0x76fe70)
">>>Line[18]" QThread(0xa772c8)
">>>Line[18]" QThread(0xa772c8)

效果

首先,这里会保证 void run(); 可以执行到 void exec(); 所以在 exec 上面的所有代码都可以执行。

但由于是外部的信号,执行的槽函数也全部是和主线程一致的。

💁🏻‍♂️Qt::ConnectionType::AutoConnection

connect(this, &MyThread::signal_test, QThread::currentThread(), task, Qt::ConnectionType::AutoConnection);
Main Thread QThread(0x12f72c8)
"Construction-Line[8]" QThread(0x12f72c8)
Object-Thread QThread(0x12f72c8)
"Run-Line[15]" MyThread(0x76fe70)
"Run-Line[27]" MyThread(0x76fe70)
">>>Line[18]" QThread(0x12f72c8)
">>>Line[18]" QThread(0x12f72c8)

效果

执行到 exec(), 槽函数在主线程执行。

AutoConnection, DirectConnection, QueuedConnection 三者的效果一致。

💁🏻‍♂️Qt::ConnectionType::DirectConnection

connect(this, &MyThread::signal_test, QThread::currentThread(), task, Qt::ConnectionType::DirectConnection);
Main Thread QThread(0x8372c8)
"Construction-Line[8]" QThread(0x8372c8)
Object-Thread QThread(0x8372c8)
"Run-Line[15]" MyThread(0x76fe70)
"Run-Line[27]" MyThread(0x76fe70)
">>>Line[18]" QThread(0x8372c8)
">>>Line[18]" QThread(0x8372c8)

效果

执行到 exec(), 槽函数在主线程执行。

💁🏻‍♂️Qt::ConnectionType::QueuedConnection

connect(this, &MyThread::signal_test, QThread::currentThread(), task, Qt::ConnectionType::QueuedConnection);
Main Thread QThread(0x9c72c8)
"Construction-Line[8]" QThread(0x9c72c8)
Object-Thread QThread(0x9c72c8)
"Run-Line[15]" MyThread(0x76fe70)
"Run-Line[27]" MyThread(0x76fe70)
">>>Line[18]" QThread(0x9c72c8)
">>>Line[18]" QThread(0x9c72c8)

效果

执行到 exec(), 槽函数在主线程执行。

💁🏻END

🌟关注我

关注我,学习更多C/C++,算法,计算机知识

B站:

👨‍💻主页:天赐细莲 bilibili

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/394243.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

最新CSS3伪类和伪元素详解

第4章 伪类和伪元素 4.1结构伪类 E:first-child{},第一个元素 样式&#xff1a; p:first-child {color: red; } <div><p>Lorem ipsum</p><p>Dolor sit amet.</p> </div> 4.1.1nth-*伪类 以计数为基础的&#xff0c;默认情况下&…

探索下一代互联网协议:IPv6的前景与优势

探索下一代互联网协议&#xff1a;IPv6的前景与优势 文章目录 探索下一代互联网协议&#xff1a;IPv6的前景与优势**IPv6 的特点****IPv6的基本首部****IPv6的地址****总结** 互联网的核心协议&#xff1a;从IPv4到IPv6 互联网的核心协议IP&#xff08;Internet Protocol&#…

Docker Deskpot出现Docker Engine Stopped的解决历程

前提&#xff1a;我的操作系统是Win11家庭版, Docker Descktop下载的是最新版&#xff08;此时是4.30.0&#xff09; 出现了如图所示的问题“Docker Engine Stopped”,个人认为解决问题的关键是第四点&#xff0c;读者可以直接看第四点&#xff0c;如果只看第四点就成功解决&am…

python开发上位机 - PyCharm环境搭建、安装PyQt5及工具

目录 简介&#xff1a; 一、安装PyCharm 1、下载 PyCharm 2、PyCharm安装 1&#xff09;配置安装目录 2&#xff09;安装选项 3、问题及解决方法 二、安装PyQt5 1、打开 Pycharm&#xff0c;新建 Project 2、安装 pyqt5 3、安装很慢怎么办&#xff1f; 4、安装 pyq…

RHCSA第三次作业

磁盘管理及分区&#xff1a; [rootMYyyy ~]# fdisk /dev/sda [rootMYyyy ~]# lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS sda 8:0 0 10G 0 disk └─sda1 8:1 0 9G 0 part sdb 8:16 0 30G 0 disk sdc …

docker 部署 mysql8

命令 docker run --restartalways --name mysql8 -v /data/mysql/conf:/etc/mysql -v /data/mysql/data:/var/lib/mysql -v /data/mysql/log:/var/log -v /data/mysql/mysql-files:/var/lib/mysql-files -p 3308:3306 -e MYSQL_ROOT_PASSWORD123456 -d mysql:8 \解释 --rest…

基于SpringBoot框架的企业财务管理系统设计与实现(论文+源码)_kaic

摘 要 在快速增长的信息时代&#xff0c;每个企业都在紧随其后&#xff0c;不断改进其办公模式。与此同时&#xff0c;各家企业的传统管理模式也逐步发生变化&#xff0c;政府和企业都将需要一个更加自动化和现代化的财务管理系统。这能够便利员工之间的信息交流和公司的工作…

day22回溯学习记录第一天- - -代码随想录

77.组合 给定两个整数 n 和 k&#xff0c;返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案。 思路:回溯的经典题目&#xff0c;回溯的整体结构类似于二叉树&#xff0c;如下图所示。据此图可知&#xff0c;采用递归是一种解决方法&#xff0c;在此引入…

定点数的运算

目录 1.定点数的移位运算 1.1算数移位 数学含义&#xff1a; 规律总结&#xff1a; 1.2逻辑移位 1.3循环移位 不带进位位 带进位位 2.定点数的加减运算 3.定点数的乘除运算 3.1原码 一位乘法 除法 3.2补码 一位乘法 除法 1.定点数的移位运算 1.1算数移位 数学…

Java日志框架

笔记学习原视频&#xff08;B站&#xff09;&#xff1a;全面深入学习多种java日志框架 目前常见日志框架有&#xff1a; JULLogbacklog4jlog4j2 目前常见的日志门面&#xff08;统一的日志API&#xff09;&#xff1a; JCLSlf4j 一、 老技术&#xff08;基本都弃用了&…

STM32——外部中断(EXTI)

目录 前言 一、外部中断基础知识 二、使用步骤 三、固件库实现 四、STM32CubeMX实现 总结 前言 外部中断&#xff08;External Interrupt&#xff0c;简称EXTI&#xff09;是微控制器用于响应外部事件的一种方式&#xff0c;当外部事件发生时&#xff08;如按键按下、传感器信号…

软件设计模式概述

模式的诞生 模式(Pattern)起源于建筑业而非软件业 模式之父——美国加利佛尼亚大学环境结构中心研究所所长Christopher Alexander&#xff08;克里斯托弗亚历山大&#xff09;博士 《A Pattern Language: Towns, Buildings, Construction》——253个建筑和城市规划模式。 他给出…

atsec增加Swift CSP评估资质

atsec信息安全评估员现已被Swift列为Swift客户安全计划&#xff08;CSP&#xff1a;Customer Security Programme&#xff09;认证评估员目录中的评估提供商&#xff0c;可以帮助全球金融机构评估其针对CSP强制性和咨询性控制的合规级别。在金融行业&#xff0c;Swift要求使用其…

MySQL的三大关键日志:Bin Log、Redo Log与Undo Log

MySQL的三大关键日志&#xff1a;Bin Log、Redo Log与Undo Log 1. Bin Log&#xff08;二进制日志&#xff09;2. Redo Log&#xff08;重做日志&#xff09;3. Undo Log&#xff08;回滚日志&#xff09; &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&…

C++现代教程四

float转string不带多余0 float a 1.2; std::tostring(a); // 1.200000 std::ostringstream strStream; strStream << a; // 1.2 if (!strStream.view().empty()) // 判定流有数据// 边框融合 float measureText(std::u8string text, FontTypes::Rectangle &recta…

科研绘图系列:R语言圆形条形图(circular barplot)

禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 介绍 圆形条形图(circular barplot)是一种条形图,其中的条形沿着圆形而不是线性排列展示。这种图表的输入数据集与普通条形图相同:每个组(一个组即一个条形)需要一个数值。(更多解释请参…

IDEA2024.2重磅发布,更新完有4G!

JetBrains 今天宣布了其 IDE 家族版本之 2024.2 更新&#xff0c;其亮点是新 UI 现在已是默认设置&#xff0c;并且对 AI Assistant &#xff08;AI助手&#xff09;进行了几项改进。 安装密道 新 UI 的设计更加简约&#xff0c;可以根据需要以视觉方式扩展复杂功能。值得开发…

Linux 下查看 CPU 使用率

目录 一、什么是 CPU 使用率二、查看 CPU 利用率1、使用 top 查看2、用 pidstat 查看3、用 ps 查看4、用 htop 查看5、用 nmon 查看6、用 atop 查看7、用 glances 查看8、用 vmstat 查看9、用 sar 查看10、dstat11、iostat 三、总结 CPU 使用率是最直观和最常用的系统性能指标&…

QT生成.exe文件无法在未安装QT的电脑上运行的解决办法

在没有安装qt的电脑上运行qt生成的exe文件&#xff0c;提示&#xff1a; The application failed to start because no Qt platform plugin could be initialized 在网上找了很多办法&#xff0c;我尝试了 手动&#xff1a; 1、修改环境变量&#xff0c;2&#xff0c;添加pla…

C#开发编程软件下载安装

1、Visual Studio 2022社区版下载 2、开始安装 3、安装进行中 。。。。