QT ObjectThread moveToThread多线程操作

news2025/1/13 17:27:50

        QT多线程专栏共有15篇文章,从初识线程到、QMutex锁、QSemaphore信号量、Emit、Sgnals、Slot主线程子线程互相传值同步变量、QWaitCondition、事件循环、QObjects、线程安全、线程同步、线程异步、QThreadPool线程池、ObjectThread多线程操作、 moveToThread等线程操作进行了全面!深入!的研究和详细的说明

        本文实现了QObjectThread多线程的使用示例,新建了四个线程同时绑定了QTextEdit进行输出,moveToThread也有详细代码教程示例。

 本文作者原创,转载请附上文章出处与本文链接。

QT ObjectThread moveToThread多线程操作目录

1 新建界面

​编辑

2 mainwindow.h

3 mainwindow.cpp

4 WorkObject.h

5 WorkObject.cpp

6 moveToThread

6.1 效果

6.2 ObjectThread.h

6.3 ObjectThread.cpp

7 mainwindow.h

8 mainwindow.cpp

9 多线程的各种操作


1 新建界面

        新建四个QTextEdit控件两个按钮

2 mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTimer>
#include <QThread>
#include <QCloseEvent>
#include "WorkObject.h"
#pragma execution_character_set("utf-8")

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

    void editInsertText1(QString strText);
    void editInsertText2(QString strText);
    void editInsertText3(QString strText);
    void editInsertText4(QString strText);
private slots:
    void on_pushButton_clicked();

    void on_pushButton_2_clicked();

private:
    Ui::MainWindow *ui;

    WorkObject* m_workList[4];
    QThread m_thread[4];

    QString Title;
    QString Version;
    QString BlogText;
};
#endif // MAINWINDOW_H

3 mainwindow.cpp

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

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    Title = "QT QObjectThread  CSDN 双子座断点 ";
    Version = "V 1.0 ";
    BlogText = "https://blog.csdn.net/qq_37529913?type=lately/";
    setWindowTitle(Title + Version + BlogText);

    m_workList[0]=new WorkObject(ui->textEdit);
    m_workList[1]=new WorkObject(ui->textEdit_2);
    m_workList[2]=new WorkObject(ui->textEdit_3);
    m_workList[3]=new WorkObject(ui->textEdit_4);

    m_workList[0]->moveToThread(&m_thread[0]);
    m_workList[1]->moveToThread(&m_thread[1]);
    m_workList[2]->moveToThread(&m_thread[2]);
    m_workList[3]->moveToThread(&m_thread[3]);

    connect(&m_thread[0],SIGNAL(started()),m_workList[0],SLOT(starWork()));
    connect(&m_thread[1],SIGNAL(started()),m_workList[1],SLOT(starWork()));
    connect(&m_thread[2],SIGNAL(started()),m_workList[2],SLOT(starWork()));
    connect(&m_thread[3],SIGNAL(started()),m_workList[3],SLOT(starWork()));

}

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


void MainWindow::on_pushButton_clicked()
{
    m_workList[0]->startThread();
    m_workList[1]->startThread();
    m_workList[2]->startThread();
    m_workList[3]->startThread();

    m_thread[0].start();
    m_thread[1].start();
    m_thread[2].start();
    m_thread[3].start();

}

void MainWindow::on_pushButton_2_clicked()
{

    m_workList[0]->stopThread();
    m_workList[1]->stopThread();
    m_workList[2]->stopThread();
    m_workList[3]->stopThread();

    QTimer::singleShot(1*1000,&m_thread[0],SLOT(terminate()));
    QTimer::singleShot(1*1000,&m_thread[1],SLOT(terminate()));
    QTimer::singleShot(1*1000,&m_thread[2],SLOT(terminate()));
    QTimer::singleShot(1*1000,&m_thread[3],SLOT(terminate()));

}

4 WorkObject.h

#ifndef WORKOBJECT_H
#define WORKOBJECT_H

#include <QObject>
#include <QTime>
#include <QDebug>
#include <QThread>
#include <QTextEdit>

#pragma execution_character_set("utf-8")

QT_BEGIN_NAMESPACE
class QListWidget;
QT_END_NAMESPACE


class WorkObject : public QObject
{
    Q_OBJECT
public:
    WorkObject(QTextEdit *listEdit,QObject *parent = 0);
    ~WorkObject();

    void stopThread();
    void startThread();
private:
  QTextEdit *m_listEdit;
  bool m_runStatus;

public slots:
  void starWork();//开始工作
};

#endif // WORKOBJECT_H


5 WorkObject.cpp

#include "WorkObject.h"

WorkObject::WorkObject(QTextEdit *listEdit, QObject *parent)
  : QObject(parent)
{
    m_listEdit=listEdit;
    m_runStatus=true;
}

WorkObject::~WorkObject()
{
}

void WorkObject::starWork()
{
    while (true)
    {
        if(!m_runStatus){
            break;
        }
        QString msg="ThreadId:" + QString::number((unsigned int)QThread::currentThreadId()) + " " + " Time:"+QTime::currentTime().toString("HH:mm:ss");
        m_listEdit->insertPlainText(msg + "\n");
        QThread::sleep(1);
    }
}

void WorkObject::stopThread()
{
    m_runStatus=false;
}

void WorkObject::startThread()
{
    m_runStatus=true;
}



//#include "WorkObject.h"

//WorkObject::WorkObject(QObject *parent)
//  : QObject(parent)
//{
//}

//WorkObject::~WorkObject()
//{
//  qDebug() << "WorkObject 销毁" << endl;
//}

//void WorkObject::objWork()
//{
//  for (int i = 0; i < 1000; ++i)
//  {
//    qDebug() << i << endl;
//  }
//  emit workFinished();
//}

//void WorkObject::starWork()
//{
//  emit workStart();
//  objWork();
//}

6 moveToThread

        以下附加核心代码、全部代码请参考最后。

6.1 效果

 

6.2 ObjectThread.h

#ifndef OBJECTTHREAD_H
#define OBJECTTHREAD_H

#include <QObject>
#include <QThread>
#include <QDebug>

#pragma execution_character_set("utf-8")

class ObjectThread : public QObject
{
    Q_OBJECT

public:
    ObjectThread(QObject *parent = nullptr);
    ~ObjectThread();

public:
    void stopThread();
    void startThread();

public slots:
    void slotStart();

private:
   bool m_runStatus;
};

#endif // OBJECTTHREAD_H

6.3 ObjectThread.cpp

#include "ObjectThread.h"
ObjectThread::ObjectThread(QObject *parent): QObject(parent)
{
    m_runStatus = false;
}
ObjectThread::~ObjectThread()
{

}

void ObjectThread::stopThread()
{
    m_runStatus=false;
}

void ObjectThread::startThread()
{
    m_runStatus=true;
}


void ObjectThread::slotStart()
{
    int i = 0;
    qDebug()<<"子线程 id"<<QThread::currentThreadId();
    while (true)
    {
        if(!m_runStatus){
            break;
        }
        qDebug()<<"线程自增:" + QString::number(++i);
        QThread::sleep(1);
    }

}

7 mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTimer>
#include <QThread>
#include <QCloseEvent>
#include "WorkObject.h"
#include "ObjectThread.h"

#pragma execution_character_set("utf-8")

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

    void editInsertText1(QString strText);
    void editInsertText2(QString strText);
    void editInsertText3(QString strText);
    void editInsertText4(QString strText);
private slots:
    void on_pushButton_clicked();

    void on_pushButton_2_clicked();


private:
    Ui::MainWindow *ui;

    QThread thread;
    ObjectThread* object;

//    WorkObject* m_workList[4];
//    QThread m_thread[4];

    QString Title;
    QString Version;
    QString BlogText;
};
#endif // MAINWINDOW_H

8 mainwindow.cpp

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

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    Title = "QT QObjectThread  CSDN 双子座断点 ";
    Version = "V 1.0 ";
    BlogText = "https://blog.csdn.net/qq_37529913?type=lately/";
    setWindowTitle(Title + Version + BlogText);


    object = new ObjectThread;

    object->moveToThread(&thread);

    connect(&thread,SIGNAL(started()),object,SLOT(slotStart()));


//    m_workList[0]=new WorkObject(ui->textEdit);
//    m_workList[1]=new WorkObject(ui->textEdit_2);
//    m_workList[2]=new WorkObject(ui->textEdit_3);
//    m_workList[3]=new WorkObject(ui->textEdit_4);

//    m_workList[0]->moveToThread(&m_thread[0]);
//    m_workList[1]->moveToThread(&m_thread[1]);
//    m_workList[2]->moveToThread(&m_thread[2]);
//    m_workList[3]->moveToThread(&m_thread[3]);

//    connect(&m_thread[0],SIGNAL(started()),m_workList[0],SLOT(starWork()));
//    connect(&m_thread[1],SIGNAL(started()),m_workList[1],SLOT(starWork()));
//    connect(&m_thread[2],SIGNAL(started()),m_workList[2],SLOT(starWork()));
//    connect(&m_thread[3],SIGNAL(started()),m_workList[3],SLOT(starWork()));



}

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


void MainWindow::on_pushButton_clicked()
{

    object->startThread();
    //object->slotStart();
    thread.start();



//    m_workList[0]->startThread();
//    m_workList[1]->startThread();
//    m_workList[2]->startThread();
//    m_workList[3]->startThread();

//    m_thread[0].start();
//    m_thread[1].start();
//    m_thread[2].start();
//    m_thread[3].start();

}

void MainWindow::on_pushButton_2_clicked()
{
    object->stopThread();
    thread.quit();
    thread.wait();

//    delete thread;
//    thread = NULL;

//    m_workList[0]->stopThread();
//    m_workList[1]->stopThread();
//    m_workList[2]->stopThread();
//    m_workList[3]->stopThread();

//    QTimer::singleShot(1*1000,&m_thread[0],SLOT(terminate()));
//    QTimer::singleShot(1*1000,&m_thread[1],SLOT(terminate()));
//    QTimer::singleShot(1*1000,&m_thread[2],SLOT(terminate()));
//    QTimer::singleShot(1*1000,&m_thread[3],SLOT(terminate()));

}

9 多线程的各种操作

以下文章均为作者原创文章,看完记得收藏、关注加👍

线程、进程、多线程、线程池一文看懂从此秒变大佬!:深入理解线程、进程、多线程、线程池_双子座断点的博客-CSDN博客

QT 初识线程(简单实现):https://blog.csdn.net/qq_37529913/article/details/110127940

QT QMutex使用详解:https://blog.csdn.net/qq_37529913/article/details/110187452

QT 线程之QSemaphore(深入理解):https://blog.csdn.net/qq_37529913/article/details/110187121

QT线程 Emit、Sgnals、Slot详细解释:https://blog.csdn.net/qq_37529913/article/details/110211435

QT 线程之QWaitCondition(深入理解):https://blog.csdn.net/qq_37529913/article/details/110212704

Qt 多线程之线程事件循环(深入理解):https://blog.csdn.net/qq_37529913/article/details/110229382

QT线程之QObjects(深入理解):https://blog.csdn.net/qq_37529913/article/details/110228837

QT线程之可重入与线程安全(深入理解):https://blog.csdn.net/qq_37529913/article/details/110224166

QT 主线程子线程互相传值:QT 主线程子线程互相传值_双子座断点的博客-CSDN博客_qt主线程给子线程传数据

QT线程同步与异步处理:QT线程同步与异步处理_双子座断点的博客-CSDN博客_qt异步线程

QT 多线程之线程池QThreadPool(深入理解):QT 多线程之线程池QThreadPool(深入理解)_双子座断点的博客-CSDN博客_qthreadpool

QT之浅拷贝、深拷贝、隐式共享(深度理解必看文章):https://blog.csdn.net/qq_37529913/article/details/110235596QT 隐式共享机制对STL样式迭代器的影响:https://blog.csdn.net/qq_37529913/article/details/110252454
 

深入理解线程、进程、多线程、线程池_线程和进程和线程池_双子座断点的博客-CSDN博客

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

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

相关文章

我的项目--初始设计

PYQT 界面1. 表&#xff1a;USER ADD键&#xff1a;USER表添加一条记录 界面2&#xff1a;

【数据结构与算法】5、循环链表、约瑟夫问题、静态链表

循环链表目录 一、单向循环链表(1) add()(2) remove()(3) 单向循环链表特点 二、双向循环链表三、约瑟夫问题&#xff08;Josephus Problem&#xff09;四、静态链表 一、单向循环链表 &#x1f33f; 单向循环链表在单链表的基础上&#xff0c;尾节点的 next 指向头节点 (1) a…

欺诈无所遁形:反欺诈(羊毛盾)API 应用解析

随着互联网的快速发展&#xff0c;欺诈行为不断演变和扩大&#xff0c;涉及的领域也越来越广泛。虚假账户注册、刷单、恶意评论、虚假广告等欺诈手段成为一些不法分子获取利益的途径。这些行为不仅损害了用户的利益&#xff0c;也对在线平台的声誉和可信度造成了威胁。为了解决…

为什么推荐用易模来制作真人手办所需的人像模型?

要问最近什么手办最流行&#xff0c;真人手办必须拥有姓名。大家看腻了传统的动漫以及游戏的周边手办以后&#xff0c;想要玩出点新花样&#xff0c;于是纷纷把眼光放到真人的身上&#xff0c;真人手办开始应运而生。 现阶段制作真人手办通常都是线下来进行&#xff0c;需要消费…

Docker安装pritunl

Background Pritunl是一款图形化的OpenVPN软件&#xff0c;提供一个友好的图形WebUI界面&#xff0c;对传统OpenVPN服务端与客户端复杂的安装配置流程进行了极大的简化&#xff0c;并且通过图形界面可以进行人员管理、参数配置&#xff0c;给予用户非常大的便捷性&#xff0c;适…

【运维】Windows 通过注册表禁用服务

【运维】Windows 通过注册表禁用服务 以这个服务为例子 Windows Push Notifications User Service 双击查看服务名称 WpnUserService_671f3 打开注册表 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\{服务名称} HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Ser…

网络基础一:网络协议初识与网络传输基本流程

目录 网络协议认识“协议”网络协议初识协议分层OSI七层模型&#xff08;理论模型&#xff09;TCP/IP五层(或四层)模型&#xff08;工程实现模型&#xff09; 网络中的地址管理MAC地址IP地址 网络传输基本流程路由的本质 数据包封装和分用网络协议需要解决的问题 网络协议 计算…

#10041. 「一本通 2.1 练习 7」门票

题目 题目描述 RPK 要带 MSH 去一个更加神秘的地方&#xff01; RPK 带着 MSH 穿过广场&#xff0c;在第 1618 块砖上按下了一个按钮&#xff0c;在一面墙上随即出现了一个把手。RPK 握住把手&#xff0c;打开了一扇石质大门。他们穿过悠长而芬芳的小道&#xff0c;走到了一扇…

基于Vue3+Vite+TS+ESLint+Prettier+Husky+lint-staged+commitlint+stylelint的项目构建

博客后台管理系统使用后的是基于Vue3ViteTSESLintPrettier的开发&#xff0c;具体项目构建如下 1、基于Vite创建vue-ts模板的项目骨架 pnpm create vite 项目名称 --template vue-ts2、安装ESLint、Prettier相关的 ESLint: 控制代码质量 Prettier: 控制代码风格 2.1、安装ESLi…

ASEMI代理NXP高压三端双向可控硅BT139-800E综合指南

编辑-Z BT139-800E是一种高压三端双向可控硅开关&#xff0c;近年来由于其卓越的性能和多功能性而广受欢迎。这种强大的半导体器件广泛应用于各种应用&#xff0c;包括电机控制、照明控制和温度调节。 BT139-800E的特点 1.高压能力&#xff1a;BT139-800E设计用于处理高压&am…

Vue Router query 命名路由 params props

6.5.路由的 query 参数 传递参数<!-- 跳转并携带query参数&#xff0c;to的字符串写法 --> <router-link :to"/home/message/detail?id${m.id}&title${m.title}">跳转</router-link><!-- 跳转并携带query参数&#xff0c;to的对象写法&am…

1753_使用Perl修改文件时间戳

全部学习汇总&#xff1a; GreyZhang/perl_basic: some perl basic learning notes. (github.com) 对于使用软件对文件进行造假的手段我一直感兴趣&#xff0c;我很想知道那些人是通过什么手段修改的文件属性。一直以来&#xff0c;我觉得修改文件的时间戳是一个很难的工作&…

Altium Designer23 设计备忘

1、新建工程 2、新建原理图 3、新建PCB 4、添加元器件SCHLIB&#xff0c;PCBLIB库 5、绘制原理图 6、给元器件添加封装 7、原理图更新至PCB 8、绘制PCB

[State of GPT] OpenAI讲座随笔记

原版&#xff1a;State of GPT B站翻译版&#xff1a;【精校版】Andrej Karpathy微软Build大会精彩演讲&#xff1a; GPT状态和原理 - 解密OpenAI模型训练 1 GPT Training Pipeline图解 记录一下对这个图的理解&#xff1a; 大模型训练的四个阶段&#xff1a; Pretraining 阶…

开发者活动:云原生的开源 AI 大模型基础设施

随着 ChatGPT 的火热&#xff0c;大语言模型和相关应用不断涌现。你是否了解大语言模型的技术细节&#xff1f;你是否曾经开发过大语言模型应用&#xff1f;如果你对大语言模型背后的基础设施感兴趣&#xff0c;那么7月8号&#xff0c;北京海淀中关村创业大街&#xff0c;云原生…

chatgpt赋能python:Python调用关系图:了解你的代码依赖关系

Python调用关系图&#xff1a;了解你的代码依赖关系 Python是一种强大的编程语言&#xff0c;具有易读易写、开放源代码、多功能等优点。但是在开发大型项目时&#xff0c;代码会变得复杂&#xff0c;不同模块之间的依赖关系也会变得混乱。为了更好地了解你的代码依赖关系&…

Openresty原理概念篇(九)LuaJIT分支和标准Lua有什么不同

一 LuaJIT分支和标准Lua有什么不同 ① 背景 luajit官方 标准lua官方 openresty自身维护的luajit 编译luajit ② LuaJIT 在 OpenResty 整体架构中的位置 ③ 标准 Lua 和 LuaJIT 的关系 ④ 为什么选择LuaJIT ⑤ lua特别之处 1&#xff09;Lua 的下标从1开始 2) 使用…

Java HelloWorld

一、java命令 javac&#xff1a;将.java文件编译成.class文件 cp - 指定class搜索路径 d - 指定class文件生成目录 java: 执行.class或.jar文件 cp指定class搜索路径 示例&#xff1a;java test1.app #表示执行./test1/app.class文件main函数 jar:打包生成.jar文件 v- 可视化输…

星星之火,可以燎原——关于太赫兹的技术进展

盼望着&#xff0c;盼望着&#xff0c;5G来了&#xff0c;6G的脚步也近了。除了做好现有的技术工作&#xff0c;作为通信人还要不断关注新技术的发展&#xff0c;真心不易&#xff01;无线数据链路的容量在过去十几年中呈指数级增长&#xff0c;但对更高数据速率的需求持续增加…

MySQL数据库优化技术一

纵论 对mysql优化时一个综合性的技术&#xff0c;主要包括 表的设计合理化(符合3NF)添加适当索引(index) [ 四种: 普通索引、主键索引、唯一索引unique、全文索引 ]分表技术( 水平分割、垂直分割 ) 水平分割根据一个标准重复定义几个字段值相同&#xff0c;表名称不同的表&…