Qt库 线程
方式一、继承QThread
步骤:
- 自定义继承于QThread的线程类
- 定义线程对象
- 调用start()接口启动线程
- 定义线程结束槽函数
- 定义线程关闭槽函数
- 绑定线程结束信号与线程结束槽函数
- 绑定窗口关闭信号和线程关闭槽函数
代码示例:
- 自定义线程类
/*mythred.h*/
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QThread>
class MyThread : public QThread
{
Q_OBJECT
public:
explicit MyThread(QObject * parent=0);
~MyThread();
protected:
void run();
signals:
void isDone();
public slots:
};
#endif // MYTHREAD_H
/*mythred.cpp*/
#include "mythread.h"
MyThread::MyThread(QObject * parent)
{
}
MyThread::~MyThread()
{
}
void MyThread::run()
{
sleep(5);
emit isDone();
}
- 界面显示类
/*widget.h*/
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include"mythread.h"
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
void dealTimeout();
void dealDone();
void stopThread();
private slots:
void on_pushButton_clicked();
private:
Ui::Widget *ui;
QTimer *myTimer;
MyThread *thread;
};
#endif // WIDGET_H
/*widget.cpp*/
#include "widget.h"
#include "ui_widget.h"
#include <QTimer>
#include <QDebug>
#include<QThread>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
myTimer = new QTimer(this);
thread = new MyThread(this);
connect(thread, &MyThread::isDone,this,&Widget::dealDone);
connect(this, &Widget::destroyed, this, &Widget::stopThread);
connect(myTimer, &QTimer::timeout, this, &Widget::dealTimeout);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_pushButton_clicked()
{
if(!myTimer->isActive()){
myTimer->start(100);
}
thread->start();
}
void Widget::dealTimeout()
{
static int i = 0;
i++;
ui->lcdNumber->display(i);
}
void Widget::dealDone()
{
qDebug() << "it is over";
myTimer->stop();
}
void Widget::stopThread()
{
thread->quit();
thread->wait();
}
- 界面布局
方式二、继承QObject
步骤:
- 自定义继承于QObject的线程类MyThread
- 定义自定义线程类(子线程)及界面类(主线程)信号
- 创建QThread主线程对象和自定义子线程对象
- 绑定子线程信号与主线程定义的信号处理函数
- 绑定主线程信号与子线程线程函数
- 把自定义线程类MyThread加到主线程QThread
代码示例:
-
自定义线程类
/*mythread.h*/ #ifndef MYTHREAD_H #define MYTHREAD_H #include <QObject> class MyThread : public QObject { Q_OBJECT public: explicit MyThread(QObject *parent = nullptr); ~MyThread(); void run(); void start(); void stop(); signals: void myThreadrun(); public slots: private: bool isRun; }; #endif // MYTHREAD_H /*mythread.cpp*/ #include "mythread.h" #include<QDebug> #include<QThread> MyThread::MyThread(QObject *parent) : QObject(parent) { } MyThread:: ~MyThread() { } void MyThread::start() { qDebug()<<"start"; this->isRun = true; } void MyThread::stop() { qDebug()<<"stop"; this->isRun = false; } void MyThread::run() { while(isRun){ QThread::sleep(1); emit myThreadrun(); qDebug() << "子线程:" << QThread::currentThread(); if(!isRun) break; } }
-
界面显示类
/*widget.h*/ #ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include "mythread.h" QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACE class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = nullptr); ~Widget(); void dealSignal(); void dealClose(); signals: void startThread(); private slots: void on_pushButtonStart_clicked(); void on_pushButton_clicked(); private: Ui::Widget *ui; MyThread *myT; QThread *thread; }; #endif // WIDGET_H /*widget.cpp*/ #include "widget.h" #include "ui_widget.h" #include<QThread> #include<QTimer> #include<QDebug> Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { ui->setupUi(this); myT = new MyThread; thread = new QThread(this); myT->moveToThread(thread); connect(myT,&MyThread::myThreadrun,this,&Widget::dealSignal); connect(this,&Widget::startThread,myT,&MyThread::run); qDebug() << "主线程:" << QThread::currentThread(); connect(this,&Widget::destroyed,this,&Widget::dealClose); } Widget::~Widget() { delete ui; } void Widget::dealSignal() { static int i = 0; i++; ui->lcdNumber->display(i); } void Widget::on_pushButtonStart_clicked() { if(thread->isRunning()) { return; } thread->start(); myT->start(); emit startThread(); } void Widget::on_pushButton_clicked() { if(!thread->isRunning()) { return; } myT->stop(); thread->quit(); thread->wait(); } void Widget::dealClose() { on_pushButton_clicked(); delete myT; }
-
界面布局