1 使用 QTimer 和 std::thread 在QLabel中播放视频
1.1 以下为实验代码,若有纰漏敬请谅解!
2 前提
2.1 在QT UI 界面中建立两个 QLabel 控件。
3 工程
3.1 mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);ui->label_1->setFrameShape(QLabel::NoFrame);ui->label_1->setScaledContents(true);ui->label_2->setFrameShape(QLabel::NoFrame);ui->label_2->setScaledContents(true);// use QTimer play videofaithVideo.open(videoFile);if(faithVideo.isOpened()){QTimer *faithTimer = new QTimer;faithTimer->setTimerType(Qt::PreciseTimer);connect(faithTimer,&QTimer::timeout,this,&MainWindow::sloFaithVideo);faithTimer->start(50);}else{qDebug() << "Read video file error.";}// use thread play...label2Thread = new std::thread(std::bind(&MainWindow::label2Run,this,&label2Image));connect(this,&MainWindow::sigLabel2Data,this,&MainWindow::sloShowData);
}MainWindow::~MainWindow()
{if(label2Thread != nullptr){delete label2Thread;}delete ui;
}void MainWindow::sloFaithVideo()
{Mat imgTmp,imgRGB;QImage imgQimage;QPixmap imgQpix;if(faithVideo.read(imgTmp)){//imgTmp.resize(110,110);cvtColor(imgTmp, imgRGB, COLOR_BGR2RGB);imgQimage = QImage(static_cast<const uchar*>(imgRGB.data), imgRGB.cols, imgRGB.rows, imgRGB.step, QImage::Format_RGB888);imgQpix = QPixmap::fromImage(imgQimage);ui->label_1->setPixmap(imgQpix);}else{faithVideo.open(videoFile);}
}void MainWindow::label2Run(QPixmap *output)
{Mat imgTmp,imgRGB;QImage imgQimage;QPixmap imgQpix;cv::VideoCapture tmpVideo(videoFile1);while(1){tmpVideo >> imgTmp;//if(tmpVideo.read(imgTmp))if(!imgTmp.empty()){cvtColor(imgTmp, imgRGB, COLOR_BGR2RGB);imgQimage = QImage(static_cast<const uchar*>(imgRGB.data), imgRGB.cols, imgRGB.rows, imgRGB.step, QImage::Format_RGB888);imgQpix = QPixmap::fromImage(imgQimage);std::unique_lock<std::mutex> lck(ltLock);*output = imgQpix;emit sigLabel2Data();}else{tmpVideo.open(videoFile1);}//调节此处延时会改变视频播放速度std::this_thread::sleep_for(std::chrono::milliseconds(5));}
}void MainWindow::sloShowData()
{QPixmap tmpImage;{std::unique_lock<std::mutex> lck(ltLock);tmpImage = label2Image;}ui->label_2->setPixmap(tmpImage);
}
3.2 mainwindow.h
== 注意:视频文件需要复制为两份==
== 注意:虽然使用了相关命名空间,但许多函数依然需要前缀==
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QLabel>
#include <QDebug>
#include <QTimer>#include<opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp> // GUI
#include <opencv2/imgproc/imgproc.hpp> // 图像处理
#include <opencv2/imgproc/types_c.h> // 类型转换 CV_BGR2RGB
#include <opencv2/imgcodecs.hpp> // 镜像
#include <opencv2/highgui/highgui_c.h>
#include <opencv2/objdetect.hpp> // 打开模型
#include <iostream>
#include <thread>using namespace cv;
using namespace std;QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();VideoCapture faithVideo;const string videoFile = "E:/QTCode/END_Low.mp4";std::thread *label2Thread;QPixmap label2Image;void label2Run(QPixmap *output);const string videoFile1 = "E:/project/END_Low.mp4";std::mutex ltLock;public slots:void sloFaithVideo();void sloShowData();
signals:void sigLabel2Data();
private:Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H