【qt创建线程两种方式】

QT使用线程的两种方式

1.案例进度条

案例解析:
如图由组件一个进度条和三个按钮组成,当点击开始的时候进度条由0%到100%,点击暂停,进度条保持之前进度,再次点击暂停变为继续,点击停止按钮进度条停止。
案例流程:
1.创建qwidget工程
2.添加四个控件,转到槽函数

【qt创建线程两种方式】_第1张图片

2.使用线程方式一

2.1创建一个类继承QThread,重写run方法

2.2mythread.cpp

#include "mythread.h"
#include 
MyThread::MyThread()
{

}
void MyThread::stop()
{
    running=false;
}
//暂停继续
void MyThread::threadStop(bool flag)
{
    pause=flag;
}
//重写run方法
void MyThread::run()
{
    qDebug()<<"线程id:"<<currentThreadId();
    while (1) {
       //触发信号
        while(running){
            while (pause) {
                msleep(100);
            }
            if(value>100)
                value=0;
            emit valChage(value++);
            msleep(100);
        }
        exit(0);
    }
}

2.3mythread.h

#ifndef MYTHREAD_H
#define MYTHREAD_H
#include 
#include 
//继承QThread重写run方法
class MyThread : public QThread
{
    Q_OBJECT
public slots:
    void stop();
    void threadStop(bool flag);
signals:
    void valChage(int);
public:
    MyThread();
    void run();
private:
    int value=0;
    bool running=true;
    bool pause=false;
};

#endif // MYTHREAD_H

2.4widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include 
#include 
#include
#include "mythread.h"
namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
signals:

    void stop();
    void threadStop(bool);
private slots:
    void on_pushButton_clicked();

    void on_pushButton_3_clicked();

    void on_pushButton_2_clicked();

private:
    Ui::Widget *ui;
    MyThread *mythread;
};
#endif // WIDGET_H

2.5widget.cpp

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

}

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

void Widget::on_pushButton_clicked()

{
    mythread= new MyThread();
    //绑定信号与槽函数
    connect(mythread,&MyThread::valChage,ui->progressBar,&QProgressBar::setValue);
    //延时
    connect(mythread,&MyThread::finished,mythread, &QObject::deleteLater);
    connect(this,&Widget::stop,mythread,&MyThread::stop);
    connect(this,&Widget::threadStop,mythread,&MyThread::threadStop);
    mythread->start();
    ui->pushButton->setEnabled(false);

}

void Widget::on_pushButton_3_clicked()
{
    emit stop();
}
void Widget::on_pushButton_2_clicked()
{
    static bool flag=true;
    if(flag){
        emit threadStop(true);
        ui->pushButton_2->setText("继续");
        flag=false;
    }else{
        emit threadStop(false);
        ui->pushButton_2->setText("暂停");
        flag=true;
    }
}

3.使用线程方式二

3.1创建类继承QObject

【qt创建线程两种方式】_第2张图片

3.2qworker.h

这里的槽函数实现直接写在.h文件中,不够规范,只便与学习观看,切不要效仿。

#ifndef QWORKER_H
#define QWORKER_H
#include 
#include 
#include 
class qworker : public QObject
{
    Q_OBJECT
public:
    explicit qworker(QObject *parent = nullptr);

signals:
    void dataChanged(int);
public slots:
    void doWorking(){
        while (!sFlag) {
            if(current>=100)
                current=0;
            while (pFlag) {
               QThread::msleep(10);
               //接收来自外部进程的事件,否则收不到信号
               QApplication::processEvents();
            }
            emit dataChanged(current++);
            QThread::msleep(10);
            QApplication::processEvents();
        }
        sFlag=false;
        current=0;
    }
     void pause(bool flag){
        pFlag=flag;
     }
     void stop(){
         sFlag=true;
     }
private:
    //进度条
    int current=0;
    //暂停
    bool pFlag=false;
    //停止
    bool sFlag=false;
};
#endif // QWORKER_H

3.3widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include 
//引入qworker.h
#include "qworker.h"

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
signals:
    void working();
    void pause(bool);
    void stop();
private slots:
    void on_pushButton_clicked();
    void on_pushButton_2_clicked();
    void on_pushButton_3_clicked();
c
private:
    Ui::Widget *ui;
    qworker *worker;
    QThread thread;
};
#endif // WIDGET_H

3.4widget.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    worker=new qworker();
    //移动到线程中
    worker->moveToThread(&thread);
    //开始
    connect(this,&Widget::working,worker,&qworker::doWorking);
    //暂停
    connect(this,&Widget::pause,worker,&qworker::pause);
    //停止
    connect(this,&Widget::stop,worker,&qworker::stop);
    connect(worker,&qworker::dataChanged,ui->progressBar,&QProgressBar::setValue);
    thread.start();
}
Widget::~Widget()
{
    delete ui;
}
void Widget::on_pushButton_clicked()
{
    emit working();
}

void Widget::on_pushButton_2_clicked()
{
    static bool flag=true;
    if(flag){
    emit pause(true);
    flag=false;
    ui->pushButton_2->setText("继续");
    }else{
        emit pause(false);
        flag=true;
        ui->pushButton_2->setText("暂停");
    }
}
void Widget::on_pushButton_3_clicked()
{
    emit stop();
}

4.总结

两种方式都可以完成案例需求:

方式一:

1.通过继承QThread类重写run方法

2.重写类MyThread的虚函数void run();,即新建一个函数protected void run(),然后对其进行定义。

3.在需要用到多线程的地方,实例MyThread,然后调用函数MyThread::start()后,则开启一条线程,自动运行函数run()。

4.当停止线程时,调用MyThread::wait()函数,等待线程结束,并且回收线程资源。

方式二:

1.继承QObject类,创建对象。

2.通过moveToThread将派生类对象移动到一个线程中。

3.通过信号连接派生类的槽函数,将耗时的工作放到这个槽函数中运行。

4.用信号QThread::finished绑定槽函数QThread::deleteLatater(),在线程退出时,自动销毁该线程和相关资源。

5.通过QThread的start()函数开启多线程。

你可能感兴趣的:(qt,qt,开发语言)