概述
本文章内容如下
- 在子线程中开启一个定时器,定时器触发timeout信号时会从摄像头拿一张图像放入队列中
- 一个按钮控制开始和暂停(也就是开始定时器和停止定时器)
主线程cameraTestTime.h和cameraTestTime.cpp
cameraTestTime.h主要代码
cameraTestTime(QWidget *parent = Q_NULLPTR);
QTimer *timer;
cv::VideoCapture *videocapture;//摄像头
QImage cvMat2QImage(const cv::Mat& mat);
std::mutex mu;
qtimerUse qtU; //定时器类
QTimer timerTest;
//定时器
QThread timerTh;
//子线程
std::queue<cv::Mat> tempMat; //存图像的队列
bool ok;
//按钮暂停还是开始
bool runFlag; //在按钮槽函数里面有一个while循环,这个是判断哪个循环是否运行的
private slots:
void test();
//定时器触发的槽
void clickButton();
//按钮触发的槽
cameraTestTime.cpp主要代码
cameraTestTime::cameraTestTime(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
connect(ui.pushButton, SIGNAL(clicked()), this, SLOT(clickButton())); //按钮信号和槽连接
videocapture = new cv::VideoCapture(0); //开启摄像头
ok = true; //这个bool用来实现按钮时开始还是暂停
//定时器和Qhread子线程的信号和槽连接
QObject::connect(&timerTest, SIGNAL(timeout()), this, SLOT(test()), Qt::DirectConnection);
QObject::connect(&qtU, SIGNAL(stopTimer()), &timerTest, SLOT(stop()));
QObject::connect(&qtU, SIGNAL(startTimer()), &timerTest, SLOT(start()));
//将定时器塞到子线程中
timerTest.moveToThread(&timerTh);
qtU.moveToThread(&timerTh);
}
void cameraTestTime::test() {
//从摄像头读图
cv::Mat matFrame;
videocapture->read(matFrame);
//将图放入队列
std::unique_lock<std::mutex> locker(mu);
{
tempMat.push(matFrame);
}
}
void cameraTestTime::clickButton() {
if (ok) { //开始
ok = false;
runFlag = true;
timerTest.setInterval(30);
timerTh.start();
qtU.start();
timeAll = clock();
while (runFlag) {
if (!tempMat.empty()) {
cv::Mat imageHandel;
{
std::unique_lock<std::mutex> locker(mu);
imageHandel = tempMat.front();
tempMat.pop();
}
//将图像显示在界面上
QImage imgg = cvMat2QImage(imageHandel);
QPixmap qpixmap = QPixmap::fromImage(imgg);
ui.label->setPixmap(qpixmap);
qApp->processEvents();
}
}
}
else { //停止
runFlag = false;
qtU.stop();
ok = true;
}
}
//图像格式转换
QImage cameraTestTime::cvMat2QImage(const cv::Mat& mat)
{
if (mat.type() == CV_8UC1)
{
QImage image(mat.cols, mat.rows, QImage::Format_Indexed8);
image.setColorCount(256);
for (int i = 0; i < 256; i++)
image.setColor(i, qRgb(i, i, i));
uchar *pSrc = mat.data;
for (int i = 0; i < mat.rows; i++)
{
uchar *pDest = image.scanLine(i);
memcpy(pDest, pSrc, mat.cols);
pSrc += mat.step;
}
return image;
}
else if (mat.type() == CV_8UC3)
{
const uchar *pSrc = (const uchar*)mat.data;
QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_RGB888);
return image.rgbSwapped();
}
else if (mat.type() == CV_8UC4)
{
const uchar *pSrc = (const uchar*)mat.data;
QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_ARGB32);
return image.copy();
}
else
{
return QImage();
}
}
定时器类qtimerUse.h和qtimerUse.cpp的主要代码
qtimerUse.h
public:
explicit qtimerUse(QObject *parent = nullptr);
~qtimerUse();
void stop();
void start();
signals:
void stopTimer();
void startTimer();
qtimerUse.cpp
void qtimerUse::stop()
{
emit stopTimer();
}
void qtimerUse::start()
{
emit startTimer();
}
最后
以上就是秀丽大雁为你收集整理的QT将定时器放在子线程并设置一个按钮来开启和关闭定时器的全部内容,希望文章能够帮你解决QT将定时器放在子线程并设置一个按钮来开启和关闭定时器所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复