文章目录

  • 源文件类
  • 实现方法 1
  • 实现方法 2
  • 总结



源文件类

python qt 多任务 多线程 qt多线程wait_qt


widget类为主线程,mythread为待创建的子线程类

python qt 多任务 多线程 qt多线程wait_qt_02


点击按钮线程开始执行(针对方法一,方法二忽略图形界面)

实现方法 1

widget.h

#include <QWidget>
#include <QThread>
#include "mythread.h"

class Widget : public QWidget
{
    Q_OBJECT
public:
    QThread * thread; // 子线程
    mythread * mth; // 子线程模块
    void closeThread();  // 关闭子线程
};

注: 上面省略掉无关代码

widget.cpp

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

    // 1. 自定义线程模块 设置该线程需要完成的任务
    mth = new mythread;

    // 2. 创建子线程 (理解为线程管理者)
    thread = new QThread(this);

    // 3. 将准备好的线程类和子线程关联
    mth->moveToThread(thread);

    // 4. 启动子线程,但是,并没有启动线程处理函数
    thread->start();

    // 5. 线程处理函数需要通过 信号-槽 调用
    connect(ui->pushButton, &QPushButton::pressed, mth, &mythread::printInfo);

    // 6. 关闭线程
    connect(this, &Widget::destroyed, this, &Widget::closeThread);
}
// 关闭线程函数
void Widget::closeThread()
{
    thread->quit(); // 退出子线程
    thread->wait(); // 回收线程资源
    delete mth; // 释放线程模块内存
}

mythread.cpp

#include "mythread.h"
#include <QDebug>
mythread::mythread(QObject *parent) : QObject(parent)
{}

void mythread::printInfo()
{
     qDebug()<<"线程正在执行..."<<endl;
//   if(true)
     //     exit(1);
}

实现方法 2

这里忽略掉ui界面

widget.h

#include <QWidget>
#include "mythread.h"

class Widget : public QWidget
{
    Q_OBJECT
public:
    mythread * thread; // 声明一个线程类对象

    void closeThread(); // 关闭线程
};

注: 省略掉无关代码

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QThread>
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    // 1. 创建线程对象
    thread = new mythread(this);

    // 2. 会间接调用mythread::run()线程处理函数开始处理数据
    thread->start();

    // 3. 线程处理函数需要通过 信号-槽 调用
    connect(thread, &mythread::isDone,this,&Widget::closeThread);
}
// 关闭线程函数
void Widget::closeThread()
{
    thread->quit(); // 退出子线程
    thread->wait(); // 回收线程资源
    delete thread; // 释放线程模块的内存
}

mythread.h

#include <QThread>

class mythread : public QThread
{
    Q_OBJECT
protected:
    //QThread的虚函数,也是线程处理函数
    //不能直接调用,通过start()间接调用,因为这是个protected函数
    void run();

signals:
    void isDone(); // 线程功能执行完毕
};

mythread.cpp

#include "mythread.h"
#include <QDebug>
mythread::mythread(QObject *parent) : QThread(parent)
{}

void mythread::run()
{
     for(int i = 0; i < 100000000; i++)
        qDebug()<<"线程正在执行..."<<endl;
     
     qDebug()<<"数据处理完毕,我要发出退出信号的"<<endl;
     emit isDone(); // 发送执行完毕信号
}

注意: mythread类的继承对象时QThread

总结

  • 注意第一个方法里面线程继承的是QObject类,而方法二里面继承的类是QThread
  • 方法一种thread->start()会启动线程但不会启动线程处理函数,方法二中会直接调用mythread::run(),且run就是线程处理函数
  • 方法一中线程处理函数可以自定义,方法二中线程处理函数固定是run()不能额外自定义
  • 方法二只需创建线程对象,然后start调用线程函数,最后关闭线程,操作比较简单;方法二需要创建两个对象然后关联,调用线程处理函数需要信号和槽触发,实现比较复杂。
  • 方法一是4.7版本之前的使用方法,方法二是4.7之后的使用方法。