Qt opens multithreading, mainly for the class QThread. There are two ways, the first is to inherit the QThread with a class, and then rewrite the virtual function run(). When you want to open a new thread, you just need to instantiate the class and then call the function start() to open a multithread. The second method is to inherit a QObject class, and then use the moveToThread() function to open a thread slot function, which will take a lot of time to calculate the code into the thread slot function.
1. Multithreading before Qt4.6
- Create a new class MyThread based on QThread.
- Rewrite the virtual function void run() of MyThread class; that is, create a new function protected void run(), and define it.
- Where multithreading is needed, instance MyThread, and then call the function MyThread::start(), a thread is opened and the function run() is automatically run. Note that you can't call run() directly, but indirectly through start ().
- When the thread is stopped, the MyThread::wait() function is called to wait for the end of the thread and reclaim the thread resources.
The sample code is as follows:
mythread.h
#ifndef MYTHREAD_H #define MYTHREAD_H #include <QThread> class MyThread : public QThread { Q_OBJECT public: explicit MyThread(QObject *parent = 0); ~MyThread(); protected: //Rewrite run function, thread execution function void run(); signals: //Signals emitted by a custom subthread after execution void isDone(); public slots: }; #endif // MYTHREAD_H
mywidget.h
#ifndef MYWIDGET_H #define MYWIDGET_H #include <QWidget> #include <QTimer> #include "mythread.h" namespace Ui { class MyWidget; } class MyWidget : public QWidget { Q_OBJECT public: explicit MyWidget(QWidget *parent = 0); ~MyWidget(); private slots: //Timer timeout processing slot function void dealTimeOut(); void on_pushButton_clicked(); //Processing Functions When Subthreads Exit void dealDone(); //The slot function for subthread exit by clicking the red fork in the upper right corner void stopThread(); private: Ui::MyWidget *ui; QTimer MyTimer; MyThread* thread; }; #endif // MYWIDGET_H
mythread.cpp
#include "mythread.h" #include <QDebug> MyThread::MyThread(QObject *parent) : QThread(parent) { } //Rewrite run function, thread execution function void MyThread::run() { int i = 0; while(i < 10) { i++; sleep(1); qDebug()<<"I am a sub-thread, mine ID yes:"<<QThread::currentThreadId(); } emit isDone(); } MyThread::~MyThread() { }
mywidget.cpp
#include "mywidget.h" #include "ui_mywidget.h" #include <QThread> #include <QDebug> MyWidget::MyWidget(QWidget *parent) : QWidget(parent), ui(new Ui::MyWidget) { ui->setupUi(this); thread = new MyThread(this); //Correlation signal and slot connect(&this->MyTimer,QTimer::timeout,this,&MyWidget::dealTimeOut); connect(thread,&MyThread::isDone,this,&MyWidget::dealDone); connect(this,&MyWidget::destroy,this,&MyWidget::stopThread); } void MyWidget::stopThread() { //Sign out thread->quit(); //Wait for the child process function to execute, then exit thread->wait(); } void MyWidget::dealDone() { MyTimer.stop(); qDebug()<<"Child Thread is Done"; } void MyWidget::dealTimeOut() { static int i = 0; i++; ui->lcdNumber->display(i); qDebug()<<"I am the main thread, mine ID Yes,"<<QThread::currentThreadId(); } MyWidget::~MyWidget() { delete ui; } void MyWidget::on_pushButton_clicked() { if(MyTimer.isActive() == false) { //Start timer MyTimer.start(100); } //Start timer thread->start(); }
The final operation results are as follows:
I am the main thread, my ID is: 0x3f14
I am the main thread, my ID is: 0x3f14
I am the main thread, my ID is: 0x3f14
I am the main thread, my ID is: 0x3f14
I am a sub-thread, my ID is: 0x36d4
Subthread is Done
2. Multithreading after Qt4.6
- Create a new class, inherit and QObject
- Create a slot function in the class to run the code in multithreading. All time-consuming codes run in this slot function.
- Instance of a myThread object of this class. Note that the parent object cannot be specified, because the parent object is specified later through moveToThread
- Instance a thread of the QThread object, at which point the parent object can be specified
- To transfer the QThread object to the instance object myThread of the new class, you can use the function void QObject::moveToThread(QMyThread *thread); for example, myThread - > moveToThread (thread)
- Start thread object thread - > start ();
- Start the slot function of the new class myThread by means of signal and slot
- The quit() and wait() functions of threads are used to wait for sub-threads to exit. Note that wait() waits until the slot function is executed before returning. If the slot function is not finished, the program may get stuck.
The sample code is as follows:
mthread.h
#ifndef MYTHREAD_H #define MYTHREAD_H #include <QObject> #include <QThread> class MyThread : public QObject { Q_OBJECT public: explicit MyThread(QObject *parent = 0); ~MyThread(); //Custom thread processing function can not be called directly, otherwise the function and the main thread are in one thread. //If the function is time-consuming, the thread will get stuck. void myTimeOut(); signals: //Custom signals to notify the main thread to perform related operations void mysignals(); public: bool isStop; public slots: }; #endif // MYTHREAD_H
mywidget.h
#ifndef MYWIDGET_H #define MYWIDGET_H #include <QWidget> #include "mythread.h" namespace Ui { class MyWidget; } class MyWidget : public QWidget { Q_OBJECT public: explicit MyWidget(QWidget *parent = 0); ~MyWidget(); signals: void myStartThread(); private slots: //Callback function of start button void on_startBtn_clicked(); //Callback function of stop button void on_pushButton_2_clicked(); //Slot function for processing subprocesses void dealSignals(); //Slot function when exiting program void stopThread(); private: //Custom Thread Class Objects MyThread* mythread; //Thread class object QThread* thread; Ui::MyWidget *ui; }; #endif // MYWIDGET_H
mypthread.cpp
#include "mythread.h" #include<QDebug> MyThread::MyThread(QObject *parent) : QObject(parent) { isStop = false; } MyThread::~MyThread() { } void MyThread::myTimeOut() { while(!isStop) { qDebug()<<"I am a sub-thread, mine ID Yes,"<<QThread::currentThreadId(); QThread::sleep(1); //Send a signal to the main thread emit mysignals(); } }
mywidget.cpp
#include "mywidget.h" #include "ui_mywidget.h" #include <QDebug> MyWidget::MyWidget(QWidget *parent) : QWidget(parent), ui(new Ui::MyWidget) { ui->setupUi(this); //Allocate space dynamically, not the parent object mythread = new MyThread; //Create subthreads thread = new QThread(this); //Adding a custom thread to a sub-thread, that is, specifying the child thread bit and the father of the custom thread mythread->moveToThread(thread); //Establish the signal and slot of main thread and sub-thread connect(mythread,&MyThread::mysignals,this,&MyWidget::dealSignals); //The thread processing function of sub-threads is invoked by means of signal and slot connect(this,&MyWidget::myStartThread,mythread,&MyThread::myTimeOut); //When the operation is closed, the thread exit operation is performed connect(this,&MyWidget::destroyed,this,&MyWidget::stopThread); qDebug()<<"I am the main thread, mine ID Yes,"<<QThread::currentThreadId(); } //Thread exit operation void MyWidget::stopThread() { if(thread->isRunning()) { mythread->isStop = true; thread->quit(); thread->wait(); } } //Main thread operates slot function according to sub-thread signal void MyWidget::dealSignals() { static int i = 0; i++; ui->lcdNumber->display(i); } MyWidget::~MyWidget() { delete ui; } //Slot function of start button void MyWidget::on_startBtn_clicked() { if(false == thread->isRunning()) { //Start subthreads, but do not start handlers for custom threads thread->start(); mythread->isStop = false; emit myStartThread(); } } //Slot function of stop button void MyWidget::on_pushButton_2_clicked() { if(thread->isRunning()) { mythread->isStop = true; thread->quit(); thread->wait(); } }
The code runs as follows:
I am the main thread, my ID is: 0x19e0
I am a sub-thread, my ID is: 0x4430
I am a sub-thread, my ID is: 0x4430