QT 多线程处理和使用
思路:
项目实例:
源码交流:
mythread.h
- #ifndef MYTHREAD_H
- #define MYTHREAD_H
- #include <QObject>
- #include <QThread>
- #include <QDebug>
- class MyThread : public QObject
- {
- Q_OBJECT
- public:
- explicit MyThread(QObject *parent = 0);
- void MyTimeout();//线程处理函数
- void setFlage(bool flag = true); //设置标志位,何时关闭子线程
- signals:
- void MySignal();
- public slots:
- protected:
- bool isStop;
- };
- #endif // MYTHREAD_H
mythread.cpp
- #include "mythread.h"
- MyThread::MyThread(QObject *parent) : QObject(parent)
- {
- isStop = false;
- }
- //线程处理函数
- void MyThread::MyTimeout()
- {
- while(false == isStop)
- {
- QThread::sleep(1);
- emit MySignal(); //每隔一秒发射一次信号
- qDebug()<<"子线程ID:"<<QThread::currentThread(); //显示当前线程的数值
- if(true == isStop)
- {
- break;
- }
- }
- }
- void MyThread::setFlage(bool flag)
- {
- isStop = flag;
- }
mywidget.h
- #ifndef MYWIDGET_H
- #define MYWIDGET_H
- #include <QWidget>
- #include "mythread.h"
- #include <QThread>
- #include <QDebug>
- namespace Ui {
- class MyWidget;
- }
- class MyWidget : public QWidget
- {
- Q_OBJECT
- public:
- explicit MyWidget(QWidget *parent = 0);
- ~MyWidget();
- void dealMySignal();
- private slots:
- void on_pushButton_clicked();
- void on_pushButton_2_clicked();
- void dealClose();
- signals:
- void startMyThread(); //启动子线程的信号
- private:
- Ui::MyWidget *ui;
- MyThread *myThread;
- QThread *thread;
- };
- #endif // MYWIDGET_H
mywidget.cpp
- #include "mywidget.h"
- #include "ui_mywidget.h"
- MyWidget::MyWidget(QWidget *parent) :
- QWidget(parent),
- ui(new Ui::MyWidget)
- {
- ui->setupUi(this);
- //创建线程对象,不能够指定父对象
- myThread = new MyThread;
- //创建子线程对象
- thread = new QThread(this);
- //把子线程(对象)添加到自定义的线程类(对象)中
- myThread->moveToThread(thread);
- connect(myThread, &MyThread::MySignal, this, &MyWidget::dealMySignal);
- qDebug()<<"主线程ID:"<<QThread::currentThread(); //显示当前线程的数值
- connect(this, &MyWidget::startMyThread, myThread, &MyThread::MyTimeout);
- connect(this, &MyWidget::destroyed, this, &MyWidget::dealClose);
- //线程处理函数内部,不允许操作图形界面
- //connect()第五个参数的作用, 连接方式: 默认, 队列,直接
- //多线程才有含义
- //默认的时候
- //如果是多线程,默认使用队列
- //如果是单线程,默认使用直接方式
- //队列:槽函数所在线程和接受(信号)者一样
- //直接:槽函数所在线程和发送(信号)者一样
- }
- MyWidget::~MyWidget()
- {
- delete ui;
- }
- //处理收到的线程的信号, 作出相应动作
- void MyWidget::dealMySignal()
- {
- static int i = 0;
- i++;
- ui->lcdNumber->display(i);
- }
- //启动子线程
- void MyWidget::on_pushButton_clicked()
- {
- if(thread->isRunning() == true) //这个判断个什么鬼?
- {
- return;
- }
- //启动子线程,但没有启动线程处理函数
- thread->start();
- myThread->setFlage(false);
- //**************************************************
- //不能够直接调用该线程处理函数
- //不然的话,都会导致线程处理函数和主线程是在同一个线程
- // myThread->MyTimeout();
- //**************************************************
- //只能够通过 signal - slot 来调用线程处理函数
- emit startMyThread();
- }
- void MyWidget::on_pushButton_2_clicked()
- {
- if(thread->isRunning() == false)
- {
- return;
- }
- myThread->setFlage(true);
- thread->quit();
- thread->wait();
- }
- void MyWidget::dealClose()
- {
- on_pushButton_2_clicked();
- delete myThread; //因为没有指定父对象,所以不释放会溢出,但是没有设么大问题
- }