zl程序教程

您现在的位置是:首页 >  后端

当前栏目

Qt5多线程

多线程 QT5
2023-09-27 14:28:42 时间

QT有两种实现多线程的方法,一种是“子类化QThread,然后去重写run函数,实现多线程”。一种是“子类化QObject,然后使用moveToThread函数实现多线程”

方法一:子类化QObject

要单独创建一个类Mythread,这个类必须继承QObject  

mythread.h文件

#ifndef MYTHREAD_H
#define MYTHREAD_H

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


class Mythread : public QObject  //必须继承与QObject
{
    Q_OBJECT
public:
    explicit Mythread(QObject *parent = nullptr);
public slots:
    void f(void);   //子线程要执行的函数
    //必须是槽函数

signals:

};

#endif // MYTHREAD_H

mythread.cpp文件

#include "mythread.h"

Mythread::Mythread(QObject *parent) : QObject(parent)
{

}

void Mythread::f()
{
    static int i=0;
    while (i<100) {
        qDebug()<<"子线程ID:"<<QThread::currentThreadId()<<", "<<i++;
        //返回当前线程ID
        QThread::sleep(1);//等待1秒

    }


}

 

win.h

#ifndef WIN_H
#define WIN_H

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

class Win : public QWidget
{
    Q_OBJECT

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

private:
    QPushButton* button;
    Mythread myo; //  创建子线程工作对象
    //注意:不要给这个工作对象指定父对象
    QThread thread;//子线程对象
signals:
    void dd();

};
#endif // WIN_H

win.cpp

#include "win.h"

Win::Win(QWidget *parent)
    : QWidget(parent)
{
    this->resize(300,200);
    button=new QPushButton("开始",this);
    button->move(10,10);

    qDebug()<<"主线程ID:"<<QThread::currentThreadId();

    myo.moveToThread(&thread);//把对象myo移到thread子线程
    connect(button,SIGNAL(clicked(void)),&myo,SLOT(f()));  //让按钮的点击信号连接工作对象的槽函数
    thread.start();//开启子线程
//启动后会发出started ()信号


}

Win::~Win()
{
}

上面工程下载地址:链接:https://pan.baidu.com/s/1oPj2q5g37NPkATgdkrIf-Q     提取码:6666    

  

 

 

方法二:子类化QThread

要单独创建一个类Myclass,这个类必须继承QThread

这种方法的优点:简单一点,缺点:每个类的子线程入口函数只有一个run

myclass.h

#ifndef MYCLASS_H
#define MYCLASS_H

#include <QThread>
#include <QDebug>

class Myclass : public QThread  //继承QThread
{
public:
    Myclass();

private:
    void run();  //重写线程入口函数-线程执行函数
    //这个函数不能直接调用


};

#endif // MYCLASS_H

myclass.cpp

#include "myclass.h"

Myclass::Myclass()
{

}

void Myclass::run()
{
    static int i=0;
    while(i<100){
        qDebug()<<"子线程ID:"<<QThread::currentThreadId()<<",  "<<i++;
        QThread::sleep(1);
    }
}

win.h

#ifndef WIN_H
#define WIN_H

#include <QWidget>
#include <QPushButton>
#include "myclass.h"

class Win : public QWidget
{
    Q_OBJECT

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

private:
    QPushButton* button;
    Myclass thread;//创建自定义的子线程对象

};
#endif // WIN_H

win.cpp

#include "win.h"

Win::Win(QWidget *parent)
    : QWidget(parent)
{
    this->resize(300,200);
    button=new QPushButton("开始",this);
    button->move(10,10);

    connect(button,SIGNAL(clicked(void)),&thread,SLOT(start()));//让按钮的点击信号连接线程对象的start槽函数
    //start槽函数开启子线程,会运行run函数
    //也可以thread.start();直接开始
}

Win::~Win()
{
}

void terminate()函数用于强制结束线程,不保证数据完整性和资源释放 

 

互斥锁QMutex

头文件声明:    #include <QMutex>