Qt QThread的moveToThread方法使用

Qt线程简介

从 Qt4.4 版本之后,因为 QThread 的 run 方法创建新线程这样实现与 Qt 设计的理念不符,Qt 主推使用 moveToThread 方法来创建新线程。QThread 应该被看做是操作系统线程的接口或控制点,而不应该包含需要在新线程中运行的代码。需要运行的代码应该放到一个 QObject 的子类中,然后将该子类的对象 moveToThread 到新线程中。主要操作步骤如下:

  1. 创建一个类对象 obj,创建一个线程对象 thread。
  2. 创建主线程中对象 M 与类对象 obj 链接的信号槽。
  3. 通过类对象 obj 的 moveToThread 方法将类对象 obj 移动到线程对象 thread 中。
  4. 调用线程对象 thread 的 start 方法,启动线程。
  5. 对象 M 调用信号槽,类对象 obj 在新线程中处理数据(调用新线程只能通过信号槽来完成,如果要将类对象 obj 的数据传回给对象 M,可以由 obj 发起对 M 的信号槽)。

具体代码如下:

1:要放入新线程的 Worker 类

h 文件:

#ifndef WORKER_H
#define WORKER_H#include <QObject>/*****************************************************************************************@copyright 2013-2020@author    qiaowei@contact   weiweiqiao@126.com@version   1.0@date      2021-01-09@brief     工人类,主要方法do_something打印工人对象所在线程的id
******************************************************************************************/
class Worker : public QObject
{Q_OBJECT
public:explicit Worker(QObject *parent = nullptr);signals:/***************************************************************************@author   qiaowei@version  1.0@date     2021-01-24@brief    调用Controller::print_thread方法***************************************************************************/void result_ready(const QString& content);public slots:/***************************************************************************@author   qiaowei@version  1.0@date     2021-01-07@brief    打印Worker对象所在线程id***************************************************************************/void do_something();};#endif // WORKER_H

cpp 文件:

#include <QtDebug>
#include <QThread>
#include "worker.h"Worker::Worker(QObject *parent) : QObject(parent)
{}void Worker::do_something()
{emit result_ready("Hello");//    int i(0);
//    while (i < 20) {
//        qDebug() << "I'm working in Worker's thread:" << (quint64) QThread::currentThreadId();
//        ++i;
//    }qDebug() << "I'm working in Worker's thread:" << (quint64) QThread::currentThreadId();
}

2:操纵 Worker 类对象的 Controller 类

h 文件:

#ifndef CONTROLLER_H
#define CONTROLLER_H#include <QObject>QT_BEGIN_NAMESPACE
class Worker;
QT_END_NAMESPACE/*****************************************************************************************@copyright 2013-2020@author    qiaowei@contact   weiweiqiao@126.com@version   1.0@date      2021-01-06@brief     控制线程创建、启动
******************************************************************************************/
class Controller : public QObject
{Q_OBJECT
public:explicit Controller(QObject *parent = nullptr);~Controller();/***************************************************************************@author   qiaowei@version  1.0@date     2021-01-06@brief    将对象worker_移入子线程work_thread_,启动子线程***************************************************************************/void move_work_to_thread();signals:/***************************************************************************@author   qiaowei@version  1.0@date     2021-01-07@brief    调用worker_::do_something方法***************************************************************************/void start_running();public slots:void print_thread() const;private:void setup_connections();void print_thread_id() const;private:/***************************************************************************@author   qiaowei@version  1.0@date     2021-01-07@brief    子线程***************************************************************************/QThread* work_thread_;/***************************************************************************@author   qiaowei@version  1.0@date     2021-01-07@brief    放入子线程work_thread_的对象worker_***************************************************************************/Worker* worker_;
};#endif // CONTROLLER_H

cpp 文件:

#include <QThread>
#include <QtDebug>
#include "controller.h"#include "worker.h"Controller::Controller(QObject *parent) :QObject(parent),work_thread_(new QThread()),worker_(new Worker())
{setup_connections();print_thread_id();move_work_to_thread();
}Controller::~Controller()
{work_thread_->quit();work_thread_->wait();delete work_thread_;if (nullptr == work_thread_) {qDebug()<< "nullptr";} else {work_thread_ = nullptr;}
}void Controller::move_work_to_thread()
{worker_->moveToThread(work_thread_);// 启动子线程。不启动子线程,worker_对象的方法不会被调用(因为运行的环境没启动)work_thread_->start();
}void Controller::print_thread() const
{
//    int i(0);
//
//    while (i < 20) {
//        print_thread_id();
//        ++i;
//    }print_thread_id();
}void Controller::setup_connections()
{connect(this,&Controller::start_running,worker_,&Worker::do_something);connect(worker_,&Worker::result_ready,this,&Controller::print_thread);
}void Controller::print_thread_id() const
{qDebug()<< "Controller::Controller = " << (quint64) QThread::currentThreadId();
}

触发线程的 ui 类

h 文件:

#ifndef CONTROLLER_DIALOG_H
#define CONTROLLER_DIALOG_H#include <QDialog>QT_BEGIN_NAMESPACE
class Controller;
QT_END_NAMESPACEnamespace Ui {
class Controller_dialog;
}/*****************************************************************************************@copyright 2013-2020@author    qiaowei@contact   weiweiqiao@126.com@version   1.0@date      2021-01-09@brief     操作多线程的ui
******************************************************************************************/
class Controller_dialog : public QDialog
{Q_OBJECTpublic:explicit Controller_dialog(QWidget *parent = nullptr);~Controller_dialog();private:void setup_connections();private:Ui::Controller_dialog *ui;Controller* controller_;
};#endif // CONTROLLER_DIALOG_H

cpp 文件:

#include "controller_dialog.h"
#include "ui_controller_dialog.h"#include "controller.h"Controller_dialog::Controller_dialog(QWidget *parent) :QDialog(parent),ui(new Ui::Controller_dialog),controller_(new Controller())
{ui->setupUi(this);setup_connections();setFixedSize(sizeHint());
}Controller_dialog::~Controller_dialog()
{delete ui;delete controller_;
}void Controller_dialog::setup_connections()
{// 启动新线程connect(ui->start_button_,&QPushButton::clicked,controller_,&Controller::start_running);// 关闭所有窗体,退出程序connect(ui->quit_button_,&QPushButton::clicked,qApp,&QApplication::closeAllWindows);
}

界面 ui:

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"><class>Controller_dialog</class><widget class="QDialog" name="Controller_dialog"><property name="geometry"><rect><x>0</x><y>0</y><width>219</width><height>83</height></rect></property><property name="windowTitle"><string>Dialog</string></property><layout class="QGridLayout" name="gridLayout"><item row="0" column="0"><layout class="QHBoxLayout" name="horizontalLayout"><item><widget class="QPushButton" name="start_button_"><property name="text"><string>Start Button</string></property></widget></item><item><widget class="QPushButton" name="quit_button_"><property name="text"><string>Quit</string></property></widget></item></layout></item></layout></widget><resources/><connections/>
</ui>

main 文件:

#include <QApplication>#include "mainwindow.h"
#include "thread_dialog.h"
#include "controller_dialog.h"int main(int argc, char *argv[])
{QApplication a(argc, argv);Controller_dialog d;d.show();return a.exec();
}

运行结果,打印 Print_thread、Worker 对象的线程号:

 可以看到打印结果,Worker 对象在线程 9480,主程序入口在线程 5336

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

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

相关文章

SIFT算法原理:SIFT算法详细介绍

前面我们介绍了Harris和Shi-Tomasi角点检测算法&#xff0c;这两种算法具有旋转不变性&#xff0c;但不具有尺度不变性&#xff0c;以下图为例&#xff0c;在左侧小图中可以检测到角点&#xff0c;但是图像被放大后&#xff0c;在使用同样的窗口&#xff0c;就检测不到角点了。…

图像处理库(Opencv, Matplotlib, PIL)以及三者之间的转换

文章目录 1. Opencv2. Matplotlib3. PIL4. 三者的区别和相互转换5. Torchvision 中的相关转换库5.1 ToPILImage([mode])5.2 ToTensor5.3 PILToTensor 1. Opencv opencv的基本图像类型可以和numpy数组相互转化&#xff0c;因此可以直接调用torch.from_numpy(img) 将图像转换成t…

初识性能测试

✏️作者&#xff1a;银河罐头 &#x1f4cb;系列专栏&#xff1a;JavaEE &#x1f332;“种一棵树最好的时间是十年前&#xff0c;其次是现在” 目录 什么是性能测试&#xff1f;为什么要做性能测试&#xff1f;性能测试常见术语及性能测试衡量指标并发用户数响应时间/平均响应…

综合与新综合与新型交通发展趋势[75页PPT]

导读&#xff1a;原文《综合与新综合与新型交通发展趋势[75页PPT]》&#xff08;获取来源见文尾&#xff09;&#xff0c;本文精选其中精华及架构部分&#xff0c;逻辑清晰、内容完整&#xff0c;为快速形成售前方案提供参考。 完整版领取方式 完整版领取方式&#xff1a; 如需…

JVM之类加载与字节码

1.类文件结构 一个简单的HelloWorld.Java package cn.itcast.jvm.t5; // HelloWorld 示例 public class HelloWorld { public static void main(String[] args) { System.out.println("hello world"); } }编译为 HelloWorld.class 后的样子如下所示&#xff1a; […

continue有什么作用

学习算法以来&#xff0c;break使用的比较多&#xff0c;continue使用的比较少&#xff0c;只知道break是跳出循环的作用,不知道continue有什么作用。 continue可以跳过本次循环&#xff0c;强制执行下一次循环。 比如这个代码 #include<iostream>using namespace std…

【C++】开源:Eigen3矩阵与线性代数库配置使用

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍Eigen3矩阵与线性代数库配置使用。 无专精则不能成&#xff0c;无涉猎则不能通。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&…

Kafka介绍

目录 1&#xff0c;kafka简单介绍 2&#xff0c;kafka使用场景 3&#xff0c;kafka基本概念 kafka集群 数据冗余 分区的写入 读取分区数据 顺序消费 顺序消费典型的应用场景&#xff1a; 批量消费 提交策略 kafka如何保证高并发 零拷贝技术&#xff08;netty&#…

微信小程序的自定义TabBar及Vant的使用

一、安装Vant 1、在 资源管理器 空白位置&#xff0c;点右键打开 在外部终端窗口打开 2、初始化NPM npm init -y 3、安装命令 npm i vant/weapp1.3.3 -S --production 4、构建NPM包 在 工具 里选择构建NPM包 5、删除style:v2 在app.json里&#xff0c;删除"style"…

AutoDL从0到1搭建stable-diffusion-webui

前言 AI绘画当前非常的火爆&#xff0c;随着Stable diffusion&#xff0c;Midjourney的出现将AI绘画推到顶端&#xff0c;各大行业均受其影响&#xff0c;离我们最近的AI绘画当属Stable diffusion&#xff0c;可本地化部署&#xff0c;只需电脑配备显卡即可完成AI绘画工作&…

宝塔面板Mysql数据库无法启动(已解决)

1、错误排查 Mysql 无法正常启动直接使用官方提供的脚本检查出错 wget -O sql-repair.sh http://download.bt.cn/install/sql-repair.sh && sh sql-repair.shwget -O sql-repair.sh http://download.bt.cn/install/sql-repair.sh && sh sql-repair.sh 打印出…

arcgis--数据库构建网络数据集

1、打开arcmap软件&#xff0c;导入数据&#xff0c;如下&#xff1a; 该数据已经过处理&#xff0c;各交点处均被打断&#xff0c;并进行了拓扑检查。 2、在文件夹下新建文件数据库&#xff0c;名称为路网&#xff0c;在数据库下新建要素类&#xff0c;并导入道路shp文件&…

【项目 计网1】4.1 网络结构模式 4.2MAC地址、IP地址、端口

文章目录 第四章 Linux网络编程4.1 网络结构模式C/S结构&#xff08;client-server&#xff09;B/S结构&#xff08;Browser/Server&#xff0c;浏览器/服务器模式&#xff09; 4.2 4.3MAC地址、IP地址、端口&#xff08;1&#xff09;&#xff08;2&#xff09;MAC地址IP地址(…

关于win11 debian wsl 子系统安装启动docker一直starting,无法启动

首先我先说明&#xff0c;我的步骤都是按照官网步骤来的 通过官网的操作步骤 通过测试命令 sudo docker run hello-world得到下面的命令&#xff0c;我们通过启动命令 sudo service docker start 执行结果如下图 也就是说无法启动&#xff0c;一直显示在启动中 遇到这种情况…

什么是多运行时架构?

服务化演进中的问题 自从数年前微服务的概念被提出&#xff0c;到现在基本成了技术架构的标配。微服务的场景下衍生出了对分布式能力的大量需求&#xff1a;各服务之间需要相互协作和通信&#xff0c;以及共享状态等等&#xff0c;因此就有了各种中间件来为业务服务提供这种分…

深度学习(35)—— StarGAN(2)

深度学习&#xff08;34&#xff09;—— StarGAN&#xff08;2&#xff09; 完整项目在这里&#xff1a;欢迎造访 文章目录 深度学习&#xff08;34&#xff09;—— StarGAN&#xff08;2&#xff09;1. build model&#xff08;1&#xff09;generator&#xff08;2&#…

K8S 部署 RocketMQ

文章目录 添加模板部署本地访问 集群使用 kubesphere 作为工具 添加模板 添加 helm 模板 helm repo add rocketmq-repo https://helm-charts.itboon.top/rocketmq helm repo update rocketmq-repo编写 value.yaml 文件 配置主从节点的个数&#xff0c;例子为单节点 broker:…

使用langchain与你自己的数据对话(四):问答(question answering)

之前我已经完成了使用langchain与你自己的数据对话的前三篇博客&#xff0c;还没有阅读这三篇博客的朋友可以先阅读一下&#xff1a; 使用langchain与你自己的数据对话(一)&#xff1a;文档加载与切割使用langchain与你自己的数据对话(二)&#xff1a;向量存储与嵌入使用langc…

动画制作选择Blender还是Maya

Blender和Maya是两种最广泛使用的 3D 建模和动画应用程序。许多经验丰富的用户表示&#xff0c;Blender 在雕刻工具方面远远领先于 Maya&#xff0c;并且在 3D 建模方面达到了相同的质量水平。对于刚接触动画行业的人来说&#xff0c;您可能会问“我应该使用 Blender 还是 Maya…

Docker入门——保姆级

Docker概述 ​ —— Notes from WAX through KuangShen 准确来说&#xff0c;这是一篇学习笔记&#xff01;&#xff01;&#xff01; Docker为什么出现 一款产品&#xff1a;开发—上线 两套环境&#xff01;应用环境如何铜鼓&#xff1f; 开发 – 运维。避免“在我的电脑…