QT_QThread线程
![在这里插入图片描述](https://img-blog.csdnimg.cn/704d7b288f024b99a3521901a6e6ed7a.png)
注意的是:在线程中不能调用槽函数,否则会出现意想不到的错误,如调用w.show等!可以发出信号让某个槽函数响应,即尽量让线程独立,解耦合。
设计对窗口的操作,都要放到槽中去做。在线程中不要做
头文件
#pragma once
#include <QThread>
#include <QMutex>
#include "opencv2/core.hpp" // Mat所在的头文件
class XVideoThread :public QThread //单件模式,不要拿这个类去创建对象,只做接口调用。
{
Q_OBJECT // 信号与槽才会有效
public:
//单件模式 获取对象
static XVideoThread* Get() //通过一个静态函数;
{
static XVideoThread vt; //这个对象只生成一个,称之为单件模式; 只能通过这个get方式获取对象,进行调用,保证 对象具有唯一性。
return &vt; //返回指针类型
}
void Play() { mutex.lock(); isPlay = true; mutex.unlock(); }; //打开视频
void Pause() { mutex.lock(); isPlay = false; mutex.unlock(); };
~XVideoThread();
//线程入口函数
void run();
signals:
protected:
QMutex mutex; //线程互斥
XVideoThread(); //构造函数放在保护中,在外部就无法用这个类去生成对象。
};
/* 如何使用这种单件模式? 接口调用方法: XVideoThread::Get()获取这个对象vt,再通过指针调用这个对象的成员函数Open。
if (!XVideoThread::Get()->Open(file))
{
QMessageBox::information(this, "error", name+" open failed!");
return;
}
*/
源文件
#include "XVideoThread.h"
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>
#include "XFilter.h"
using namespace std;
using namespace cv;
void XVideoThread::run() //注意的是,当线程被销毁的时候,这个线程有可能没被销毁,导致关闭程序时显示程序被shutdown掉。
{
for (;;)
{
mutex.lock(); //锁的原则,尽晚调用,尽早退出
if (isexit)
{
mutex.unlock(); //尽早退出,一定不能遗漏
break;
}
if (!isPlay) //如果处于暂停
{
mutex.unlock();
msleep(5);
continue;
}
msleep(s); //根据fps设定帧间隔
mutex.unlock(); //一定记得各个条件下都要退出
}
}
XVideoThread::XVideoThread()
{
start(); //线程启动。XVideoThread继承public QThread 这个类,XVideoThread中重载了void run();函数,则调用start()后,则会创建一个线程,并把run()函数变成入口函数
}
XVideoThread::~XVideoThread()
{
// terminate(); //粗暴的终止线程。
mutex.lock(); //线程先锁住。
isexit = true; //等待一次run()函数中for循环完毕后,将isexit标志位置为真,run()函数结束。 相当于线程退出操作quit(); 。
mutex.unlock(); //线程解掉
wait(); //等待线程的退出!!! 必须在这里等待线程执行完退出
}