0


QT -- 多线程 —— moveToThread

视频教程链接: 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>classMy_Task:public QObject
{Q_OBJECTpublic:
    explicit My_Task(QObject *parent = nullptr);voidtask_01();voidtask_02();signals:voidtask_01_signal(int value);voidtask_02_signal(int value);publicslots:};

#endif // MY_TASK_H

my_task.cpp

#include "my_task.h"
#include "unistd.h"My_Task::My_Task(QObject *parent):QObject(parent){}voidMy_Task::task_01(){
    int i=0;for(;;){
        emit task_01_signal(i++);sleep(1);sleep(1);if(i>10){break;}}}voidMy_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(newUi::MainWindow){
    ui->setupUi(this);
    task1 =newMy_Task;// 不要给定父对象
    my_thread1 =newQThread(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 =newMy_Task;// 不要给定父对象
    my_thread2 =newQThread(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>classMy_Task:public QObject
{Q_OBJECTpublic:
    explicit My_Task(QObject *parent = nullptr);voidtask_01();voidtask_02();signals:voidtask_01_signal(int value);voidtask_02_signal(int value);publicslots: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){}voidMy_Task::task_01(){if(value1>10){return;}
    emit task_01_signal(value1++);}voidMy_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(newUi::MainWindow){
    ui->setupUi(this);
    task1 =newMy_Task;// 不要给定父对象
    my_thread1 =newQThread(this);
    task1->moveToThread(my_thread1);
     my_thread1->start();connect(task1,&My_Task::task_01_signal,[=](int val){
       ui->lcdNumber->display(QString::number(val));});

    task2 =newMy_Task;// 不要给定父对象
    my_thread2 =newQThread(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;}voidMainWindow::timerEvent(QTimerEvent *event){if(event->timerId()== timer1){
         task1->task_01();
        task2->task_02();}}voidMainWindow::on_btnStart_clicked(){/* startTimer()功能是启动计时器并返回计时器标识符,如果不能启动计时器则返回零 *//* 计时器事件将每间隔 1000 毫秒发生一次,直到killTimer()被调用。*/
     timer1 =startTimer(1000);}

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

标签: qt ui 开发语言

本文转载自: https://blog.csdn.net/xuechanba/article/details/127868971
版权归原作者 xuechanba 所有, 如有侵权,请联系我们删除。

“QT -- 多线程 —— moveToThread”的评论:

还没有评论