Qt创建线程(使用moveToThread方法创建子线程)

1.moveTothread方法:

(1)要使用moveToThread方法必须继承与QObject类

(2)创建任务对象时不能指定父对象

例子:

MyWork* work = new MyWork(this); // error

MyWork* work = new MyWork; // ok

(3)任务类里面的任务函数可以有多个

(4)这种创建线程的方式很灵活,如果子线程不够用,可以把多个任务函数移动到其中的一个线程中,(一个子线程中可以移动多个任务函数,关联的多个任务函数是按照线性的顺序执行的)还可以先在线程1中执行任务函数a,然后在线程2中执行任务函数a(也就是一个任务函数可以在多个不同的线程中执行)

QThread和moveToThread两种方法都可以使用信号和槽

2.使用moveToThread方法实现点击开始按钮生成10000个随机数,然后分别使用冒泡排序和快速排序排序这10000个随机数,最后在窗口显示排序后的数字:

mainwindow.h文件:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();
signals:void starting(int num);
private:Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

mythread.h文件:

#ifndef MYTHREAD_H
#define MYTHREAD_H
#include<QObject>
#include <QThread>
//生成随机数 第二种写法继承于QObject实现的多线程
class MyThread : public QObject
{Q_OBJECT
public:explicit MyThread(QObject *parent = nullptr);void working(int num);
signals:void sendArray(QVector<int> list);
};class BubbleSort : public QObject
{Q_OBJECT
public:explicit BubbleSort(QObject *parent = nullptr);void working(QVector<int> list);
signals:void finish(QVector<int> num);
};class QuickSort : public QObject
{Q_OBJECT
public:explicit QuickSort(QObject *parent = nullptr);void working(QVector<int> list);
private:void quickSort(QVector<int> &list, int l, int r);
signals:void finish(QVector<int> num);
};#endif // MYTHREAD_H

main.cpp文件:

#include "mainwindow.h"#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);qRegisterMetaType<QVector<int>>("QVector<int>");MainWindow w;w.show();return a.exec();
}

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "mythread.h"
#include<QThread>
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);//1.创建子线程的对象QThread *t1 = new QThread;//QThread *t1 = new QThread(this); //1.创建子线程时指定父对象为this就可以在线程结束时自动释放线程//2.在当前窗口析构的时候,回收线程的资源QThread *t2 = new QThread;QThread *t3 = new QThread; //创建三个子线程,现在系统中一共有四个线程(三个子线程和一个主线程)//2.创建任务类的对象MyThread *gen = new MyThread;BubbleSort *bubble = new BubbleSort;QuickSort *quick = new QuickSort;//3.将任务对象移动到某个子线程中gen->moveToThread(t1);bubble->moveToThread(t2);quick->moveToThread(t3);connect(this, &MainWindow::starting, gen, &MyThread::working);//2.启动子线程connect(ui->start, &QPushButton::clicked, this, [=]{emit starting(10000); //在启动子线程时,将要生成的随机数的个数发送出去t1->start();});//接收子线程发送的数据connect(gen, &MyThread::sendArray, bubble, &BubbleSort::working); //先关联再启动线程connect(gen, &MyThread::sendArray, quick, &QuickSort::working); //这里任务函数是在子线程中执行的/* connect(gen, &MyThread::sendArray, this,[](QVector<int> list){//如果信号和槽函数不在同一个线程的情况bubble->working(list);quick->working(list);}); *///注意:此时这个匿名函数是在当前的主线程中执行的,但是我们是想让他在子线程中执行,这样就错误了,不满足我们的需求了connect(gen, &MyThread::sendArray, this, [=](QVector<int> list){ //connect里面不支持传递QVector类型//需要使用qRegisterMetaType()进行注册t2->start();t3->start();for(int i = 0; i < list.size(); i++){ui->randList->addItem(QString::number(list.at(i)));}});connect(bubble, &BubbleSort::finish, this, [=](QVector<int> list){ //connect里面不支持传递QVector类型//需要使用qRegisterMetaType()进行注册for(int i = 0; i < list.size(); i++){ui->bubbleList->addItem(QString::number(list.at(i)));}});connect(quick, &QuickSort::finish, this, [=](QVector<int> list){ //connect里面不支持传递QVector类型//需要使用qRegisterMetaType()进行注册for(int i = 0; i < list.size(); i++){ui->quickList->addItem(QString::number(list.at(i)));}});//2.当前窗口析构的时候,回收线程的资源//窗口关闭时,会发送一个destroyed()信号,就可以根据这个信号来销毁线程的资源connect(this, &MainWindow::destroyed, this,[=]{t1->quit();t1->wait();t1->deleteLater(); //delete t1 销毁线程t1的资源t2->quit();t2->wait();t2->deleteLater(); //delete t2 销毁线程t2的资源t3->quit();t3->wait();t3->deleteLater(); //delete t3 销毁线程t3的资源gen->deleteLater(); //释放任务对象genbubble->deleteLater(); //释放任务对象bubblequick->deleteLater(); //释放任务对象quick});\
}MainWindow::~MainWindow()
{delete ui;
}

mythread.cpp文件:

#include "mythread.h"
#include <QVector>
#include <QElapsedTimer> //计算某个流程执行所使用的时间
#include <QDebug>
#include <QThread>
MyThread::MyThread(QObject *parent): QObject(parent)
{}void MyThread::working(int num)
{qDebug() << "生成随机数的线程地址" << QThread::currentThread(); //获取一个指针,这个指针指向当前线程对象的地址QVector<int> list;QElapsedTimer time;time.start();for(int i = 0; i < num; i++){list.push_back(qrand() % 100000);}int milsec = time.elapsed();qDebug() << "生成" << num << "个随机数总共用时:" << milsec << "毫秒";emit sendArray(list);
}BubbleSort::BubbleSort(QObject *parent):QObject(parent)
{}void BubbleSort::working(QVector<int> list)
{qDebug() << "冒泡排序的线程地址" << QThread::currentThread(); //获取一个指针,这个指针指向当前线程对象的地址QElapsedTimer time;time.start();for(int i = 0; i < list.size() - 1 ;i++){for(int j = 0;j < list.size() - i - 1; j++){if(list[j] > list[j + 1]){int temp = list[j];list[j] = list[j + 1];list[j + 1] = temp;}}}int milsec = time.elapsed();qDebug() << "冒泡排序用时" << milsec << "毫秒";emit finish(list);
}QuickSort::QuickSort(QObject *parent):QObject(parent)
{}void QuickSort::quickSort(QVector<int> &s, int l, int r)
{if(l < r){int i = l, j = r;int x = s[l];while(i < j){while(i < j &&s[j] >=x){j--;}if(i < j){s[i++] = s[j];}while(i < j && s[i] < x){i++;}if(i < j){s[j--] = s[i];}}s[i] = x;quickSort(s, l, i - 1);quickSort(s, i + 1, r);}
}void QuickSort::working(QVector<int> list)
{qDebug() << "快速排序的线程地址" << QThread::currentThread(); //获取一个指针,这个指针指向当前线程对象的地址QElapsedTimer time;time.start();quickSort(list, 0,list.size()-1);int milsec = time.elapsed();qDebug() << "快速排序用时" << milsec << "毫秒";emit finish(list);
}

运行结果:

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

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

相关文章

InputAction的使用

感觉Unity中InputAction的使用&#xff0c;步步都是坑。 需求点介绍 当用户长按0.5s 键盘X或者VR left controller primaryButton (即X键)时&#xff0c;显示下一个图片。 步骤总览 创建InputAction资产将该InputAction资产绑定到某个GameObject上在对应的script中&#xf…

[Linux]多线程编程

[Linux]多线程编程 文章目录 [Linux]多线程编程pthread_create函数pthread_join函数pthread_exit函数pthread_cancel函数pthread_self函数pthread_detach函数理解线程库和线程id Linux操作系统下&#xff0c;并没有真正意义上的线程&#xff0c;而是由进程中的轻量级进程&#…

9、SpringBoot_日志使用

三、日志 1.日志的使用 使用 RestController public class LogController {public static final Logger log LoggerFactory.getLogger(LogController.class);GetMapping("/index")public String index(){log.info("请求info 信息");log.debug("请…

Django的设计模式及模板层

Django的设计模式及模板层 设计模式MVC和MVT MVC 代表 Model-View-Controller(模型-视图-控制器)模式。 M 模型层(Model),主要用于对数据库层的封装 V 视图层(View),用于向用户展示结果 (WHAT HOW) C 控制(Controller&#xff0c;用于处理请求、获取数据、返回结果(重要) 作…

JetBrains常用插件

Codota AI Autocomplete Java and JavaScript&#xff1a;自动补全插件 Background Image plus&#xff1a;背景图片设置 rainbow brackets&#xff1a;彩虹括号&#xff0c;便于识别 CodeGlance2&#xff1a; 类似于 Sublime 中的代码缩略图&#xff08;代码小地图&#xff…

抽象轻松java

嗨嗨嗨&#xff01; 没想到吧&#xff0c;出现了抽象轻松第4种语言系列&#xff08;我也没想到&#xff09; 简单的java程序&#xff0c;看完就懂的简单逻辑——购物车系统 购物车&#xff0c;首先要有商品吧&#xff0c;现实中的商品有什么属性&#xff1f; 名字&#xff0…

Oracle 12c自动化管理特性的新进展:自动备份、自动恢复和自动维护功能的优势|oracle 12c相对oralce 11g的新特性(3)

一、前言: 前面几期讲解了oracle 12c多租户的使用、In-Memory列存储来提高查询性能以及数据库的克隆、全局数据字典和共享数据库资源的使用 今天我们讲讲oracle 12c的另外的一个自动化管理功能新特性:自动备份、自动恢复、自动维护的功能 二、自动备份、自动恢复、自动维护…

IntelliJ IDEA 介绍、安装、配置优化与快捷键大全

一、简介 IDEA全称 IntelliJ IDEA&#xff0c;是Java编程语言的集成开发环境。IntelliJ在业界被公认为最好的Java开发工具&#xff0c;尤其在智能代码助手、代码自动提示、重构、JavaEE支持、各类版本工具(git、svn等)、JUnit、CVS整合、代码分析、 创新的GUI设计等方面的功能…

分布式并行训练(DP、DDP、DeepSpeed)

[pytorch distributed] 01 nn.DataParallel 数据并行初步 数据并行 vs. 模型并行 数据并行&#xff1a;模型拷贝&#xff08;per device&#xff09;&#xff0c;数据 split/chunk&#xff08;对batch切分&#xff09; 每个device上都拷贝一份完整模型&#xff0c;每个device分…

Mysql高级语句(视图表 、存储过程、条件语句、循环语句)

Mysql高级语句&#xff08;视图表 、存储过程、条件语句、循环语句&#xff09; 一、 CREATE VIEW&#xff08;视图&#xff09;1.1、 视图表概述1.2、 视图表能否修改&#xff1f;&#xff08;面试题&#xff09;1.3、 基本语法1.3.1、 创建1.3.2、 查看1.3.3 、删除 1.4、 通…

喜报 |海云安斩获鲲鹏应用创新大赛2023广东赛区双料大奖!

近日&#xff0c;由深圳市工业和信息化局、深圳市南山区人民政府、深圳市南山区工业和信息化局指导&#xff0c;华为技术有限公司、深圳市金融攻关基地、广东省信息技术应用创新产业联盟、鲲鹏产业源头创新中心&#xff08;深圳&#xff09;有限公司主办&#xff0c;深圳市软件…

MySQL查询表结构方法

MySQL查询数据库单个表结构代码 – 查询数据库表信息 SELECT​ COLUMN_NAME 列名,​ DATA_TYPE 字段类型,​ CHARACTER_MAXIMUM_LENGTH 长度,​ IS_NULLABLE 是否为空,​ IF(column_key PRI,Y,) 是否为主键,​ COLUMN_DEFAULT 默认值,​ COLUMN_COMMENT 备注FROM​ INFORMAT…

数据分发服务(DDS, Data Distribution Service)简介

什么是DDS &#xff1f; 工业物联网成熟的数据连接标准 OMG 数据分发服务 (DDS™) 是一个中间件协议和 API 标准&#xff0c;用于来自 Object Management Group (OMG) 的以数据为中心的连接。它将系统的组件集成在一起&#xff0c;提供业务和关键任务物联网 (IoT) 应用程序所…

华为杯数学建模比赛经验分享

再过一周左右,第二十届华为杯数学建模比赛就要开赛了&#xff0c;所以今天分享一下个人数学建模比赛的经验。 今天给大家分享一期关于华为杯数学建模比赛的经验分享&#xff0c;我将从以下三个方面展开说明&#xff1a; &#xff08;1&#xff09;如何准备数学建模比赛&#x…

开辟ICT新视野 直通华为云专家:一堂华为云Astro低代码启蒙课 ——华为云HCSD校园沙龙之西安站

在快速发展的信息时代&#xff0c;ICT&#xff08;即&#xff1a;信息和通信技术&#xff09;行业成为众多高校应届生进军的最新领域。但刚步入大学校园的学生&#xff0c;仍困扰于「我应该如何抓住这一趋势&#xff1f;怎样规划职业生涯才切实可行&#xff1f;」。 在飘溢激动…

vue+element plus 使用table组件,清空用户的选择项

<el-table ref"tableRef"> .... </el-table> <script lang"ts" setup> import { onMounted, reactive, ref, nextTick } from vue const clearBtn () > {console.log(清空用户的选择项)tableRef.value.clearSelection() } </scr…

八大排序详解

目录 1.排序的概念及应用 1.1 排序的概念 1.2 排序的应用 1.3 常见的排序算法 2.常见排序算法的实现 2.1 直接插入排序 2.1.1 基本思想 2.1.2 动图解析 2.1.3 排序步骤&#xff08;默认升序&#xff09; 2.1.4 代码实现 2.1.5 特性总结 2.2 希尔排序 2.2.1 基本思…

数据结构与算法基础-(3)

&#x1f308;write in front&#x1f308; &#x1f9f8;大家好&#xff0c;我是Aileen&#x1f9f8;.希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流. &#x1f194;本文由Aileen_0v0&#x1f9f8; 原创 CSDN首发&#x1f412; 如…

Java 多线程基础

文章目录 1. 认识线程1.1 概念1.1.1 线程是什么1.1.2 为什么要有线程1.1.3 进程和线程的区别1.1.4 Java的线程和操作系统线程的关系 1.2 第一个多线程程序1.3 创建线程1.4 多线程的优势 2. Thread 类及其常用的方法2.1 Thread 的常见构造方法2.2 Thread 的几个常见属性2.3 启动…

EasyExcel导出转换@ExcelProperty注解中converter不生效,以及EasyExcel导入日期转换失败问题

用EasyExcel做导出&#xff0c;需要用ExcelProperty做格式转换&#xff0c;比如日期转换&#xff0c;枚举类转换 然后新建一个转换类 里面有两个实现方法&#xff0c;converToJavaData是导入时&#xff0c;数据转换定义格式&#xff0c;converToExcelData是导出时做数据转换的。…