去年这个时候,做了一个很简单的项目,需要实现多线程,找了一些资料,发现QT中不能用C++的<pthread.h>里面的多线程函数。不过QT自己开发了QThread类,通过简单的继承,可以同样实现多线程,这里就大概介绍一下。
1. 第一步,创建自己的类并继承QThread类
比如我这里做的是关于图像的线程,命名为thread_image。先把代码列出来。
【thread_image.h】
#ifndef THREAD_IMAGE_H
#define THREAD_IMAGE_H
#include <QThread>
#include "my_pthread.h"
class thread_image : public QThread
{
Q_OBJECT
public:
thread_image();
~thread_image();
protected:
void run();
signals:
void isDoneImage();
signals:
public slots:
};
#endif // THREAD_IMAGE_H
【thread_image.cpp】
#include "thread_image.h"
thread_image::thread_image()
{
}
thread_image::~thread_image()
{
cvReleaseCapture(&My_Capture);
cvDestroyAllWindows();
}
void thread_image::run()
{
image();//qt中用run函数实现多线程时,函数中不能出现cvwaitkey()函数
emit isDoneImage();
解释一下:
1.run()函数是QThread类下的实现多线程最重要的的函数,我们要做的就是实现这个函数,在函数中实现你需要的线程函数即可。
2.此处我要在多线程中实现image()函数【image()函数在thread_image.h中定义和实现】,就只需要吧image()加入run()函数中即可。
3.emit是发射指令,可以在线程结束后,发送信号给主程序,用来做线程结束后的处理,可以不用,此处不赘述。
2. 第二步,在mainwindow中实例化已经定义的类
实例化这个类后,就可以用QThread的内置函数来控制此对象中线程的开启和关闭了,代码如下:
【mainwindow.cpp】
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include "thread_image.h"
#include <QMainWindow>
#include <QDebug>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_Start_clicked();
void stop_Thread();
void Close_UI();
void on_Image_Thread_clicked();
private:
Ui::MainWindow *ui;
thread_image *Thread_Image;
bool Start_Close_Flag;
};
#endif // MAINWINDOW_H
【mainwindow.h】
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
Start_Close_Flag=false;
Thread_Image=new thread_image();
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_Start_clicked()
{
if(Start_Close_Flag==false)
{
if(ui->Image_Thread->isChecked())
{
Image_Thread_Flag=true;
Thread_Image->start();
}
}
else
{
if(ui->Image_Thread->isChecked())
{
Image_Thread_Flag=false;
Thread_Image->quit();
//Thread_Image->wait();
}
Start_Close_Flag=false;
ui->Start->setText("Start");
}
}
void MainWindow::stop_Thread()
{
Thread_Image->quit();
}
void MainWindow::Close_UI()
{
Parameter->close();
State_Panel->close();
Parameter->Delete_UI();
}
void MainWindow::on_Image_Thread_clicked()
{
if(Start_Close_Flag==false)
return;
else
{
if(ui->Image_Thread->isChecked())
{
Image_Thread_Flag=true;
Image_Init();
Thread_Image->start();
}
else
{
Image_Thread_Flag=false;
Thread_Image->quit();
//Thread_Image->wait();
}
}
}
解释一下:
1.首先,有些函数是我自己在【image.cpp】里面定义的,如果报错,直接删除就好了。
2.最重要的部分是 Thread_Image->start(); 这里面的start()函数也是QThread的内置函数,用来启动run()函数,也就是创建一个线程,执行你实现的run()。
3.另外,**Thread_Image->quit();**会强制结束你的线程,可以在不需要此线程的时候使用,但是很容易报错,谨慎使用。
4.最后,**Thread_Image->wait();**此函数会等待你的线程退出,再继续执行,用于一些同步,不过很荣易陷入程序无限等待的境地,谨慎使用。