QT -- 多线程 —— moveToThread

news2025/3/3 19:29:16

视频教程链接: https://www.bilibili.com/video/BV1fL4y1V7QP/?spm_id_from=333.880.my_history.page.click&vd_source=b91967c499b23106586d7aa35af46413

moveToThread函数的功能:给多个任务(比如显示多个界面)各分配一个线程去执行。这样就避免了自定义好多个类继承自QThread类,从而可以避免冗余。
在这里插入图片描述
翻译:更改此对象(继承自QObject类)及其子对象(继承自QObject类的子类,比如QDialog、QWidget)的线程关联关系。如果对象有父对象,则不能移动该对象。事件处理将在targetThread中继续。

在这里插入图片描述
要将对象移动到主线程,请使用QApplication::instance()来检索指向当前应用程序的指针,然后使用QApplication::thread()来检索应用程序所在的线程。

在这里插入图片描述
如果targetThread为0,则该对象及其子对象的所有事件处理都将停止。

使用moveToThread函数的流程如下:
1、创建一个类继承自QObject类或其子类,并在其中定义所要执行的多个任务,执行多个任务就要定义相应的信号。
2、任务通过moveToThread指定所要执行的线程。
3、线程通过start启动
4、通过信号与槽机制触发线程的执行

示例代码:
my_task.h

#ifndef MY_TASK_H
#define MY_TASK_H

#include <QObject>

class My_Task : public QObject
{
   	Q_OBJECT
public:
    explicit My_Task(QObject *parent = nullptr);
    void task_01();
    void task_02();

signals:
    void task_01_signal(int value);
    void task_02_signal(int value);

public slots:
};

#endif // MY_TASK_H

my_task.cpp

#include "my_task.h"
#include "unistd.h"

My_Task::My_Task(QObject *parent) : QObject(parent)
{
}

void My_Task::task_01()
{
    int i=0;
    for(;;)
    {
        emit task_01_signal(i++);sleep(1);
        sleep(1);
        if(i>10)
        {
            break;
        }
    }
}

void My_Task::task_02()
{
    int i=0;
    for(;;)
    {
        emit task_02_signal(i++);
        sleep(1);
 		if(i>10)
        {
            break;
        }
    }
}

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
	QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    task1 = new My_Task; // 不要给定父对象
    my_thread1 = new QThread(this);
    task1->moveToThread(my_thread1);
 	my_thread1->start();
    connect(ui->btnStart, &QPushButton::clicked,task1,&My_Task::task_01);
     connect(task1,&My_Task::task_01_signal,[=](int val){
       ui->lcdNumber->display(QString::number(val));
    });

	task2 = new My_Task; // 不要给定父对象
    my_thread2 = new QThread(this);
    task2->moveToThread(my_thread2);
    my_thread2->start();
	connect(ui->btnStart, &QPushButton::clicked,task2,&My_Task::task_02);
    connect(task2,&My_Task::task_02_signal,[=](int val){
       ui->lcdNumber_2->display(QString::number(val));
    });
    connect(this, &QObject::destroyed,[=](){
        my_thread1->exit();
        my_thread1->wait();
		delete task1;
    });
    connect(this, &QObject::destroyed,[=](){
        my_thread2->exit();
        my_thread2->wait();
		delete task2;
    });
}

MainWindow::~MainWindow()
{
    delete ui;
}

运行效果如下,程序有问题,并非并发,有个线程会卡住。
在这里插入图片描述
思考改进:使用定时器代替sleep,在定时器事件中执行任务函数
改进后代码如下,
my_task.h

#ifndef MY_TASK_H
#define MY_TASK_H

#include <QObject>

class My_Task : public QObject
{
   	Q_OBJECT
public:
    explicit My_Task(QObject *parent = nullptr);
    void task_01();
    void task_02();

signals:
    void task_01_signal(int value);
    void task_02_signal(int value);

public slots:

private:
    int value1=0;
    int value2=0;
};

#endif // MY_TASK_H

my_task.cpp

#include "my_task.h"
#include "unistd.h"

My_Task::My_Task(QObject *parent) : QObject(parent)
{
}

void My_Task::task_01()
{
    if(value1>10)
    {
        return;
    }
    emit task_01_signal(value1++);
}

void My_Task::task_02()
{
    if(value2>10)
    {
        return;
    }
    emit task_02_signal(value2++);
}

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
	QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    task1 = new My_Task; // 不要给定父对象
    my_thread1 = new QThread(this);
    task1->moveToThread(my_thread1);
 	my_thread1->start();
    
     connect(task1,&My_Task::task_01_signal,[=](int val){
       ui->lcdNumber->display(QString::number(val));
    });

	task2 = new My_Task; // 不要给定父对象
    my_thread2 = new QThread(this);
    task2->moveToThread(my_thread2);
    my_thread2->start();
	
    connect(task2,&My_Task::task_02_signal,[=](int val){
       ui->lcdNumber_2->display(QString::number(val));
    });
}

MainWindow::~MainWindow()
{
    my_thread1->quit();
    my_thread1->wait();
    my_thread2->quit();
    my_thread2->wait();
    delete task1;
    delete task2;
    delete ui;
}

void MainWindow::timerEvent(QTimerEvent *event)
{
    if(event->timerId() == timer1)
    {
     	task1->task_01();
        task2->task_02();
    }
}

void MainWindow::on_btnStart_clicked()
{
    /* startTimer()功能是启动计时器并返回计时器标识符,如果不能启动计时器则返回零 */
  	/* 计时器事件将每间隔 1000 毫秒发生一次,直到killTimer()被调用。*/
     timer1 = startTimer(1000);
}

运行效果如下,点击按钮后,第一下会慢。
请添加图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基金交易场景下,如何利用 Apache APISIX 来稳固 API 安全

王晔倞&#xff0c;Apache APISIX Committer&#xff0c;公众号「头哥侃码」作者。 背景介绍 金融领域的企业中&#xff0c;安全是非常重中之重的因素。 通常各类金融企业都会花费大量成本去采购安全相关的设备和硬件&#xff0c;基金管理相关企业更是如此。 根据相关国内基金…

在window和Linux上使用docker安装RocketMQ

1.创建namesrv服务 拉取镜像 docker pull rocketmqinc/rocketmq:latest启动 namesrv docker run -d -p 9876:9876 -v D:/programCoding/Docker/rocketmq/namesrv/logs:/root/logs -v D:/programCoding/Docker/rocketmq/namesrv/store:/root/store --name rmqnamesrv -e &quo…

信息论随笔(二)信息熵及其性质

回顾 上次讲到自信息量&#xff0c;也就是用来表示一个发生概率为p的事件含有的信息量&#xff0c;或者说不确定度。一个事件的发生的概率越小&#xff0c;它的不确定度越大&#xff0c;含有的信息量也就越大。 信息熵 那么如何来衡量一个系统&#xff08;多个事件以不同的概…

Java项目:眼镜商城系统(java+SSM+JSP+jQuery+Mysql)

源码获取&#xff1a;俺的博客首页 "资源" 里下载&#xff01; 项目介绍 管理员角色包含以下功能&#xff1a; 管理员登录,管理员管理,管理商城会员,新闻公告管理,眼睛类型管理,城市信息管理,连锁配镜店管理,眼镜商品管理,用户订单管理,管理用户的评价信息等功能。 …

【数据库数据恢复】SQL SERVER数据库MDF (NDF)或LDF损坏怎么恢复数据?

SQL SERVER数据库故障类型&#xff1a; MDF&#xff08;NDF&#xff09;或LDF损坏。 SQL SERVER故障原因&#xff1a; 1、数据库正在操作过程中&#xff0c;机器突然断电&#xff1b; 2、人为误操作。 SQL SERVER故障表现&#xff1a; 1、数据库在管理器界面显示处于“置疑”…

深度学习必备Python基础知识充电1

一、Python解释器运行程序 也被称之为对话模式 就是进行人机交互 1.1 算术计算 >>> 12 3 >>> 9-6 3 >>> 6*3 18 >>> 9/3 3.0 >>> 4/5 0.8 >>> 1/3 0.3333333333333333 >>> 3**9 19683 >>> 3**2 9 &…

故障分析 | DROP 大表造成数据库假死

作者&#xff1a;岳明强 爱可生北京分公司 DBA 团队成员&#xff0c;人称强哥&#xff0c;朝阳一哥等&#xff0c;负责数据库管理平台的运维和 MySQL 问题处理。擅长对 MySQL 的故障定位。 本文来源&#xff1a;原创投稿 *爱可生开源社区出品&#xff0c;原创内容未经授权不得随…

CSS实现步骤进度条——前端每日一练

CSS实现步骤进度条效果展示HTML布局文件CSS样式JavaScript操作逻辑补充&#xff1a;JavaScript的this关键字效果展示 HTML布局文件 总体布局&#xff0c;一个大div盒子包裹所有内容&#xff0c;里面划分为div button&#xff0c;六个⭕分别对应着六个子div&#xff1b;⭕下方…

带你了解S12直播中的“黑科技”

摘要&#xff1a;让精彩更流畅、让较量更清晰、让参与更沉浸、让体验更有趣&#xff0c;幕后的舞台&#xff0c;从来都是技术的战场&#xff0c;S12背后的名场面同样场场高能。本文分享自华为云社区《用硬核方式打开S12名场面》&#xff0c;作者&#xff1a;华为公众号。 让精…

WebDAV之葫芦儿·派盘+账本(简洁记账)

账本(简洁记账) 支持webdav方式连接葫芦儿派盘。 简洁记账-轻便,记账好帮手! 便捷好用的生活记账本,适用于学生记账,学生账本,亲子账本,装修记账,旅游记账,旅行记账,生意记账,人情记账,日常记账,家庭账本,随手记账等。再也不担心钱花哪儿了,简洁的记账流程,清…

从 WinDbg 角度理解 .NET7 的AOT玩法

一&#xff1a;背景 1.讲故事 前几天 B 站上有位朋友让我从高级调试的角度来解读下 .NET7 新出来的 AOT&#xff0c;毕竟这东西是新的&#xff0c;所以这一篇我就简单摸索一下。 二&#xff1a;AOT 的几个问题 1. 如何在 .NET7 中开启 AOT 功能 在 .NET7 中开启 AOT 非常方…

Linux-环境变量

&#x1f680;每日鸡汤&#xff1a; 智者重因&#xff0c;庸者重果&#xff0c;顺道而行。 目录 一、基本概念 ⅠPATH ①把我们的可执行程序拷贝到系统 /usr/bin/中 ②配置环境变量 Ⅱ getenv函数 Ⅱ user环境变量 Ⅲ PWD环境变量 二、shell变量(本地变量)和环境变量 三…

Adobe 2023全家桶已就位,拉高你的生产力,新增功能很奈斯

按照惯例。Adobe是每年一次大版本更新&#xff0c;并且是在每年的10月份中下旬&#xff0c;现在Adobe 2023终于来啦重磅更新&#xff0c;强势来袭&#xff01;​不用怀疑&#xff0c;全家桶简直是设计师福音&#xff0c;每次的大版本更新&#xff0c;为全世界的艺术设计相关人士…

Qt 样式设置

Qt 样式设置样式语法指定控件 Selector Types盒子模型 The Box Model能自定义样式的控件Sub-Controls控件的状态 Pseudo-States属性内置图标多个设置冲突层叠样式 Cascading继承规则 Inheritance子窗口不继承父窗口样式移除控件旧样式添加 .qss 文件Qt 预置颜色QLineEdit 样式设…

创建一个中国人的类

/*** 创建一个中国人的类* 分析&#xff1a;* 1、每个中国人都有一个唯一的身份证号码&#xff0c;所以身份证号码属性需要定义成实例变量* 2、每个人的姓名也都是不一样的&#xff0c;为此姓名属性也需要定义成实例变量* 3、每个中国人的国籍…

python实现目标检测voc格式标签数据增强

文章目录前言一、显示图片&#xff08;可关闭&#xff09;二、创建图像变换的类1.增强数据代码2.图像加噪声3.调整图像亮度4.添加黑色像素块5.旋转图像6.图像裁剪7.平移图像8.图像镜像9.图像随机增强选择三、增强后图片保存与xml解析保存1.从xml文件中提取bounding box信息2.保…

数据结构:循环队列

之前已经做过队列的学习笔记&#xff0c;这一篇写的是循环队列&#xff0c;大部分代码可以继续沿用&#xff0c;某些地方需要作出更改&#xff0c;使其可以实现循环队列的功能。 通俗的总结一下队列的操作&#xff0c;我的思路是将头指针固定不动&#xff0c;然后每一次元素入…

模拟实现string

第一部分&#xff1a;构造&#xff0c;析构&#xff0c;拷贝构造&#xff0c;赋值重载&#xff0c;打印函数这几个大头写出来先 string类框架 namespace xxx { class string { public: // //private: char* _str; size_t _size; size_t _capacity;const static size_t npos -…

计算机视觉——python在一张图中画多条ROC线

在验证分类算法的好坏时&#xff0c;经常需要用到AUC曲线&#xff0c;而在做不同分类模型的对比实验时&#xff0c;需要将不同模型的AUC曲线绘制到一张图里。 计算机视觉——python在一张图中绘制多个模型的对比ROC线1. 小型分类模型对比&#xff0c;可以直接调用的2. 大型的CN…

七夕,程序员教你5个表白代码,2分钟学会,牢牢主抓她的心

七夕。一个有人欢喜有人愁的节日&#xff0c;虽然对一些单身人士不太友好&#xff0c;但还有不少人都在等这个节日进行表白。毕竟这个日子的成功率会高一些。 情人节少不了送花送礼物&#xff0c;作为一个程序员&#xff0c;当然不会在送什么礼物上给你指点一二&#xff0c;但…