Qt学习之线程---movetothread的使用

在Qt中使用多线程,目前就我使用过的有两种,一是子类化QThread,重写run函数,在run函数里实现自己的代码,这一部分代码通常是比较耗时,或者干脆直接阻塞的。比如一个while循环,设置一个标志,判断循环结束。
这样写的话,会有一些东西需要了解。
子类化QThread的方法,只有run函数里面的内容是执行在子线程里的,其他的部分,比如槽函数什么的还是在主线程里执行(假设是在主线程开启的该子线程)。

还有一种方法,是子类化QObject,新建一个线程,然后使用MoveToThread把这个类的对象移到新建的线程中,这种做法使得它所有的槽函数都是执行在新开辟的线程里面。

个人推荐使用第二种方法,下面是一个demo

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <QTimer>

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

    //分配空间,但不指定父对象
    myT = new Worker;
    //创建子线程
    thread = new QThread(this);
    //把自定义线程加到子线程中
    myT->moveToThread(thread);

    connect(this, &Widget::startThreadB, myT, &Worker::mywork);
    connect(myT, &Worker::mySignal, this, &Widget::startThreadA);


    //当按窗口右上角x时,窗口触发destroyed()
        connect(this, &Widget::destroyed, this, &Widget::stopThread);


        timer = new QTimer(this);
        connect(timer ,&QTimer::timeout, this, &Widget::time);
void Widget::stopThread()
{
    //停止线程
    thread->quit();
    //等待线程处理完手头动作
    thread->wait();
}

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

void Widget::on_a_clicked()
{
        timer->start(3000);
}

void Widget::startThreadA()
{

        //QThread::sleep(3);
        qDebug()<<"主线程ID"<<QThread::currentThread();

}

void Widget::time()
{
    //启动线程处理函数
    thread->start();
    emit startThreadB();
}

void Widget::on_pushButton_clicked()
{
    timer->stop();
}
 

worker.cpp

#include "worker.h"
#include <QDebug>
#include <QThread>

Worker::Worker(QObject *parent) : QObject(parent)
{


}
void Worker::mywork()
{
    emit mySignal();

        qDebug()<<"子线程ID"<<QThread::currentThread();
 }

}

Worker::~Worker()
{

}

widget.h

#ifndef WIDGET_H
#define WIDGET_H

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

namespace Ui {
class Widget;
class QTimer;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
    void startThreadA();
    void stopThread();

private slots:
    void on_a_clicked();
    void time();
    void on_pushButton_clicked();

private:
    QTimer *timer;
    Ui::Widget *ui;
    Worker *myT;
    QThread *thread;

signals:
    void startThreadB(); //启动子线程的信号
};

#endif // WIDGET_H
 

worker.h

#ifndef WORKER_H
#define WORKER_H

#include <QObject>

class Worker : public QObject
{
    Q_OBJECT
public:
    explicit Worker(QObject *parent = 0);
    ~Worker();

    //线程处理函数
    void mywork();

signals:
    void mySignal();

public slots:
};

#endif // WORKER_H
 

需要注意的是

void MyWidget::on_buttonStart_clicked()
{

    if(thread->isRunning() == true)
    {
        return;
    }

    //启动线程,但是没有启动线程处理函数
    thread->start();
    myT->setFlag(false);

    //不能直接调用线程处理函数,
    //直接调用,导致,线程处理函数和主线程是在同一个线程
    //myT->myTimeout();

    //只能通过 signal - slot 方式调用
    emit startThread();


}

猜你喜欢

转载自blog.csdn.net/qq_37192076/article/details/81148114
今日推荐