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

news2024/11/18 11:49:02

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_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    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(); //释放任务对象gen
        bubble->deleteLater(); //释放任务对象bubble
        quick->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.coloradmin.cn/o/1032530.html

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

相关文章

常用的深度学习自动标注软件

0. 简介 自动标注软件是一个非常节省人力资源的操作&#xff0c;而随着深度学习的发展&#xff0c;这些自动化标定软件也越来越多。本文章将会着重介绍其中比较经典的自动标注软件 1. AutoLabelImg AutoLabelImg 除了labelimg的初始功能外&#xff0c;额外包含十多种辅助标注…

vue3——pixi初学,编写一个简单的小游戏,复制粘贴可用学习

pixi官网 小游戏效果 两个文件夹 一个index.html 一个data.js //data.js import { reactive } from "vue"; import { Sprite, utils, Rectangle, Application, Text, Graphics } from "pixi.js";//首先 先创建一个舞台 export const app new Applicat…

基于开源模型的实时人脸识别系统(九):软件说明

续 人脸识别_CodingInCV的博客-CSDN博客 文章目录 前言简介模型选择的要求总体流程图人脸检测人脸跟踪人脸质量人脸关键点人脸识别代码结构人脸识别的逻辑高阶设置 前言 前面的文章我们介绍了整个系统里的关键步骤&#xff0c;基于这些步骤我们就可以搭建出属于自己的人脸识别…

Java 并发编程面试题——Lock 与 AbstractQueuedSynchronizer (AQS)

目录 1.Lock1.1.Lock 是什么&#xff1f;1.2.Lock 接口提供了哪些 synchronized 关键字不具备的主要特性&#xff1f;1.3.✨Lock 与 synchronized 有什么区别&#xff1f;1.4.Lock 接口中有哪些方法&#xff1f;1.5.哪些类实现了 Lock 接口&#xff1f; 2.AbstractQueuedSynchr…

使用YOLOv5-C3模块识别图像天气 - P8

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 | 接辅导、项目定制&#x1f680; 文章来源&#xff1a;K同学的学习圈子 目录 环境步骤环境设置引用包全局设备对象 数据准备数据集信息收集图像预处理读取数据…

【Vue】模块基本语法

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;在这里&#xff0c;我要推荐给大家我的专栏《Vue快速入门》。&#x1f…

什么是WhatsApp群发,WhatsApp协议,WhatsApp云控

那么WhatsApp群控云控可以做什么呢&#xff1f; 1、获客 自动化引流&#xff0c;强大的可控性&#xff0c;产品快速拓客 2、导流 一键式傻瓜化自动加好友&#xff0c;群发&#xff0c;朋友圈营销 3、群控 一键式拉群好友&#xff0c;建群&#xff0c;进群 …

精通git,没用过git cherry-pick?

前言 git cherry-pick是git中比较有用的命令&#xff0c;cherry是樱桃&#xff0c;cherry-pick就是挑樱桃&#xff0c;从一堆樱桃中挑选自己喜欢的樱桃&#xff0c;在git中就是多次commit中挑选一个或者几个commit出来&#xff0c;也可以理解为把特定的commit复制到一个新分支…

大模型应用发展的方向|代理 Agent 的兴起及其未来(上)

“ 介绍了人工智能代理的历史渊源与演进&#xff0c;接着探讨了大型语言模型&#xff08;LLMs&#xff09;的发展&#xff0c;以及它们在知识获取、指令理解、泛化、规划和推理等方面所展现出的强大潜力。在此基础上&#xff0c;提出了一个以大型语言模型为核心的智能代理概念框…

[论文笔记]P-tuning v2

引言 今天带来第五篇大模型微调论文笔记P-tuning v2: Prompt Tuning Can Be Comparable to Fine-tuning Across Scales and Tasks。 作者首先指出了prompt tuning的一些不足,比如在中等规模的模型上NLU任务表现不好,还不能处理困难的序列标记任务,缺乏统一应用的能力。 然…

【学习草稿】背包问题

一、01背包问题 图解详细解析 &#xff08;转载&#xff09; https://blog.csdn.net/qq_37767455/article/details/99086678 &#xff1a;Vi表示第 i 个物品的价值&#xff0c;Wi表示第 i 个物品的体积&#xff0c;定义V(i,j)&#xff1a;当前背包容量 j&#xff0c;前 i 个物…

Vue中的自定义指令详解

文章目录 自定义指令自定义指令-指令的值&#xff08;给自定义指令传参数&#xff09; 自定义指令 自定义指令&#xff1a;自己定义的指令&#xff0c;可以封装一些dom 操作&#xff0c;扩展额外功能&#xff08;自动聚焦&#xff0c;自动加载&#xff0c;懒加载等复杂的指令封…

2006-2022年上市公司彭博ESG数据

2006-2022年彭博ESG数据 1、时间&#xff1a;2006-2022年 2、指标&#xff1a; Stkcd、Year、BloombergS、BloombergESG、BloombergE、BloombergG 3、指标解释&#xff1a; 彭博企业社会责任披露指数(Bloomberg ESG Disclo-sure Scores)&#xff0c;包括ESG综合得分以及环境、社…

Mac使用CMakeList编译ImGUi项目

文章目录 创建项目1.下载ImGui2.下载GLAD3.下载GLFW4.编译项目5.运行截图 创建项目 我这里创建一个demo&#xff0c;opengl这个是可以跨平台的&#xff0c;所以在mac上使用ImGui的opengl3示例 1.下载ImGui 我使用的是docking版本的&#xff0c;这个版本支持停靠功能&#xff…

Python学习 day01(注意事项)

注释 变量 数据类型的转换 运算符 / 的结果为浮点数。若// 的两边有一个为浮点数&#xff0c;则结果为浮点数&#xff0c;否则为整数。 字符串

JavaScript - canvas - 将图片保存到本地

效果 示例 项目结构&#xff1a; 源码&#xff1a; <!DOCTYPE html> <html><head><meta charset"utf-8"><title>将图片保存到本地</title></head><body><canvas id"canvas"></canvas><b…

第一百五十一回 自定义组件综合实例:游戏摇杆二

文章目录 内容回顾实现方法位置细节示例代码我们在上一章回中介绍了如何实现 游戏摇杆相关的内容,本章回中将继续介绍这方面的知识.闲话休提,让我们一起Talk Flutter吧。 内容回顾 我们在上一章回中介绍了游戏摇杆的概念以及实现方法,并且通过示例代码演示了实现游戏摇杆的…

《计算机视觉中的多视图几何》笔记(9)

现在进入本书的part 2了&#xff0c;标题是Two-View Geometry。第9-14章都隶属于part 2&#xff0c;这一部分涵盖了两个透视图的几何形状知识&#xff0c;这些视图可以像在立体设备中同时获取&#xff0c;或者例如通过相对于场景移动的相机顺序获取。这两种情况在几何上是等价的…

Java基于SpringBoot的校园博客系统

第一章&#xff1a;简介 本系统主要根据博主的需求做出分析&#xff0c;让博主更好的在线查看校园博客系统信息等&#xff0c;管理员后台管理系统数据等功能。从这个系统的操作来说&#xff0c;能够有效的进行信息的添加、修改、查询、删除一些校园博客系统信息&#xff0c;在…

【深度学习实验】前馈神经网络(七):批量加载数据(直接加载数据→定义类封装数据)

目录 一、实验介绍 二、实验环境 1. 配置虚拟环境 2. 库版本介绍 三、实验内容 0. 导入必要的工具包 1. 直接加载鸢尾花数据集 a. 加载数据集 b. 数据归一化 c. 洗牌操作 d. 打印数据 2. 定义类封装数据 a. __init__(构造函数&#xff1a;用于初始化数据集对象) b.…