【PySide6】QLabel显示视频流

1、为界面添加组件

这里为界面简单的添加一个PushButton,其他不变,效果如下图。
在这里插入图片描述

2、编写主体函数

2.1、初始化

初始化部分主要分为两大块,一是初始化信号槽,二是初始化视频捕获函数和Qt定时器。

#使用控制播放和暂停
self.num =1
#初始化视频捕获函数
self.cap = cv2.VideoCapture()
#初始化定时器
self.timer = QtCore.QTimer(self)
#初始化信号槽
self.init_slot()

信号槽的内容如下

def init_slot(self):
   #开始绑定信号和槽
   #选择视频文件
	self.ui.select.clicked.connect(self.open_video)
	#播放视频
	self.ui.begin.clicked.connect(self.play_video)
	#清空
	self.ui.clear.clicked.connect(self.clear)
	#定时器计时结束,关联显示函数
	self.timer.timeout.connect(self.show_img)
    pass

2.2、选择视频文件

 选择文件,做了简单的处理。

def open_video(self):
        video_name=None
        video_name,_ = QtWidgets.QFileDialog.getOpenFileName(self,"选择","./video/","*.mp4")
        if video_name!=None:
            self.video_name = video_name
        else:
            msg = QMessageBox.warning(self,'!','未选择文件,请重新选择!',QMessageBox.Yes)

2.3、播放视频

 播放视频,详细解释看注释吧。

def play_video(self):
        #关闭视频流阻塞信号
        self.timer.blockSignals(False)
        #第一次,定时器未激活,打开视频文件,设置定时器时间,播放标志 playing = True ,按钮设置为"暂停"
        if self.timer.isActive() is False:
            self.cap.open(self.video_name)
            self.timer.start(30)
            self.playing = True
            self.change_btn_state()
        #定时器已激活,视频已被读取,设置一个num标志判断视频状态是播放还是暂停
        #self.num 为奇数,说明视频处于播放状态,再次点击则变为暂停状态
        #那么,阻塞计时器,playing = False,num++,按钮设置为"开始"
        elif self.timer.isActive() is True and self.num%2 ==1:
            self.timer.blockSignals(True)
            self.play = False
            self.num +=1
            self.change_btn_state()
        #定时器已激活,视频已被读取,
        #self.num 为偶数,说明视频处于暂停状态,再次点击则变为播放状态
        #那么,阻塞信号为False,playing = True,num++,按钮设置为"暂停"
        elif self.timer.isActive() is True and self.num%2 ==0:
            self.num = self.num + 1
            self.timer.blockSignals(False)
            self.playing = True
            self.change_btn_state()
        #其他情况,报错
        else:
            QMessageBox.information(self, "警告", "视频播放错误!", QMessageBox.Ok)

2.4、释放资源

 释放资源,关闭视频流;计时器停止,播放停止,按钮设置为"开始"。

#释放资源,关闭视频流
#计时器停止,播放停止,按钮设置为"开始"
def close_file(self):
    self.cap.release()
    self.timer.stop()
    self.playing = False
    self.change_btn_state()

2.5、展示视频帧

 这里和显示图片的内容别无二致,视频的一帧也是图片。

def show_img(self):

	#读取图片
	#im = cv2.imread(img_name)
	#获取高和宽
	label = self.ui.label
	ret,im = self.cap.read()
	if ret:
	try:
	    ih,iw ,_ = im.shape
	    #获取标签的长和高
	    w = label.geometry().width()
	    h = label.geometry().height()
	    #上述的目的是为了保持原始的纵横比
	    if iw/w >ih/h:
	        scal = w/iw
	        nw = w
	        nh = int(scal * ih)
	        im_new = cv2.resize(im,(nw,nh))
	    else:
	        scal = w/iw
	        nw = int(scal*iw)
	        nh = h
	        im_new = cv2.resize(im,(nw,nh))
	    frame = cv2.cvtColor(im_new,cv2.COLOR_BGR2RGB)
	    im = QImage(frame.data,frame.shape[1],frame.shape[0],frame.shape[2] * frame.shape[1],
	                QImage.Format_RGB888)
	    label.setPixmap(QPixmap.fromImage(im))
	except Exception as e:
	    print(repr(e))

2.5、清空

 清空QLabel上的内容,并释放资源

def clear(self):
	self.ui.label.clear()
    self.close_file()
    pass

2.6、其他

 这里来控制按钮的状态

def change_btn_state(self):
   if self.playing:
        self.ui.begin.setText("暂停")
    else:
        self.ui.begin.setText("开始")

2.7、完整代码

from PySide6.QtWidgets import QApplication,QMainWindow,QMessageBox
from PySide6 import QtWidgets,QtCore
from PySide6.QtGui import QImage,QPixmap

from ui.Ui_mainwin import Ui_MainWindow


import sys
import cv2
import warnings

warnings.filterwarnings('ignore')

class MainWin(QMainWindow):
    def __init__(self):
        super().__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.show()
        self.num =1
        self.cap = cv2.VideoCapture()
        self.timer = QtCore.QTimer(self)
        self.init_slot()
    def init_slot(self):
        #开始绑定信号和槽
        self.ui.select.clicked.connect(self.open_video)
        self.ui.begin.clicked.connect(self.play_video)
        self.ui.clear.clicked.connect(self.clear)
        self.timer.timeout.connect(self.show_img)
        pass
    def open_video(self):
        video_name=None
        video_name,_ = QtWidgets.QFileDialog.getOpenFileName(self,"选择","./video/","*.mp4")
        if video_name!=None:
            self.video_name = video_name
        else:
            msg = QMessageBox.warning(self,'!','未选择文件,请重新选择!',QMessageBox.Yes)
    def play_video(self):
        #关闭视频流阻塞信号
        self.timer.blockSignals(False)
        #第一次,定时器未激活,打开视频文件,设置定时器时间,播放标志 playing = True ,按钮设置为"暂停"
        if self.timer.isActive() is False:
            self.cap.open(self.video_name)
            self.timer.start(30)
            self.playing = True
            self.change_btn_state()
        #定时器已激活,视频已被读取,设置一个num标志判断视频状态是播放还是暂停
        #self.num 为奇数,说明视频处于播放状态,再次点击则变为暂停状态
        #那么,阻塞计时器,playing = False,num++,按钮设置为"开始"
        elif self.timer.isActive() is True and self.num%2 ==1:
            self.timer.blockSignals(True)
            self.play = False
            self.num +=1
            self.change_btn_state()
        #定时器已激活,视频已被读取,
        #self.num 为偶数,说明视频处于暂停状态,再次点击则变为播放状态
        #那么,阻塞信号为False,playing = True,num++,按钮设置为"暂停"
        elif self.timer.isActive() is True and self.num%2 ==0:
            self.num = self.num + 1
            self.timer.blockSignals(False)
            self.playing = True
            self.change_btn_state()
        #其他情况,报错
        else:
            QMessageBox.information(self, "警告", "视频播放错误!", QMessageBox.Ok)
    #释放资源,关闭视频流
    #计时器停止,播放停止,按钮设置为"开始"
    def close_file(self):
        self.cap.release()
        self.timer.stop()
        self.playing = False
        self.change_btn_state()
    def change_btn_state(self):
        if self.playing:
            self.ui.begin.setText("暂停")
        else:
            self.ui.begin.setText("开始")
    def show_img(self):

        #读取图片
        #im = cv2.imread(img_name)
        #获取高和宽
        label = self.ui.label
        ret,im = self.cap.read()
        if ret:
            try:
                ih,iw ,_ = im.shape
                #获取标签的长和高
                w = label.geometry().width()
                h = label.geometry().height()
                #上述的目的是为了保持原始的纵横比
                if iw/w >ih/h:
                    scal = w/iw
                    nw = w
                    nh = int(scal * ih)
                    im_new = cv2.resize(im,(nw,nh))
                else:
                    scal = w/iw
                    nw = int(scal*iw)
                    nh = h
                    im_new = cv2.resize(im,(nw,nh))
                frame = cv2.cvtColor(im_new,cv2.COLOR_BGR2RGB)
                im = QImage(frame.data,frame.shape[1],frame.shape[0],frame.shape[2] * frame.shape[1],
                            QImage.Format_RGB888)
                label.setPixmap(QPixmap.fromImage(im))
            except Exception as e:
                print(repr(e))
                
    def clear(self):
        self.ui.label.clear()
        self.close_file()
        pass

if __name__=='__main__':
    app = QApplication(sys.argv)
    window = MainWin()
    sys.exit(app.exec())

3、视频演示

4、相关博客

【PySide6】PySide6安装及VSCode配置PySide6环境
【PySide6】登录和注册信号绑定以及代码实现
【PySide6】实现登录界面向主界面跳转
【PySide6】在QLabel上显示一张图片

  • 7
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鲸可落

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值