Pyqt5 Qtdesigner实现视频播放与显示信息同步GUI

Qtdesigner界面设计
可视化界面

可视化界面

Part1 Qtimer定时器

如果在应用程序中周期性地进行某项操作,则需要用到QTimer定时器。QTimer类提供了重复和单次的定时器,要使用定时器,需要先创建一个QTimer实例,将其Timeout信号连接到槽函数,并调用start(),然后,定时器,会以恒定的间隔发出timeout信号。
本文使用Qtimer计时器控制读取每帧视频与其对应txt文件在TextBrowser控件显示实现视频的播放与显示信息的同步

Part2 逐帧读取视频并显示

class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
	self.ui = u1.Ui_MainWindow()
	self.ui.setupUi(self)
	self.n = 1
    self.cap = cv2.VideoCapture(str('./gaokong/高空作业4.avi'))
    self.timer1 = QTimer(self)
    self.timer1.timeout.connect(self.timer_TimeOut)
    self.initUI()
def initUI(self):
    # 视频播放
    self.lblpic = QLabel(self)
    self.lblpic.resize(768, 432) #视频播放窗口大小
    self.lblpic.move(696, self.height() / 2 - self.lblpic.height() / 2) #视频播放窗口位置
    self.lblpic.setScaledContents(True)
	
    def timestart(self):
        self.timer1.start(10)  # 单位为毫秒

    def timepause(self):
        self.timer1.stop()

    def timer_TimeOut(self):
        frame_count = self.cap.get(cv2.CAP_PROP_FRAME_COUNT) #视频帧数
        # print(frame_count)
        self.n += 1
        if self.n > frame_count:
            self.n = 1
            self.timer1.stop()
            self.cap = cv2.VideoCapture(str('./gaokong/高空作业4.avi'))
        # 视频txt帧播放
        ret, frame = self.cap.read()
        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        img = QtGui.QImage(frame, frame.shape[1], frame.shape[0], QtGui.QImage.Format_RGB888)
        self.pm = QPixmap.fromImage(img)
        self.lblpic.setPixmap(self.pm)
        

Part3 按钮事件

   # 按钮事件,openvideo、pausevideo为按钮控件名称
    self.ui.openvideo.clicked.connect(self.timestart)
    self.ui.pausevideo.clicked.connect(self.timepause)

Part4 逐帧读取txt文件并进行显示

txt文件命名为1.txt格式

		#设置字体大小
		font = QtGui.QFont()
        font.setPointSize(25)
        font1 = QtGui.QFont()
        font1.setPointSize(20)
        self.ui.check1.setFont(font1)
        self.ui.check2.setFont(font1)
        self.ui.check3.setFont(font1)
        self.ui.check4.setFont(font1)
        # 视频出现过的总人数
        txtcount = open('./gaokong/answer/txtcount/' + str(self.n) + '.txt', 'r', encoding='utf-8')
        self.ui.txtcount.setText(txtcount.read())
        self.ui.txtcount.setFont(font)
        # 当前画面出现人数
        txti = open('./gaokong/answer/txti/' + str(self.n) + '.txt', 'r', encoding='utf-8')
        self.ui.txti.setText(txti.read())
        self.ui.txti.setFont(font)
        # 视频画面中出现人员姓名及位置
        try:
            with open('./gaokong/answer/IDlab/' + str(self.n) + '.txt', 'r', encoding='gbk') as IDlab:
                self.ui.textBrowser.setText(IDlab.read())
        except FileNotFoundError:
            with open('./gaokong/answer/IDlab/' + str(self.n) + '.txt', 'a+', encoding='gbk') as IDlab:
                self.ui.textBrowser.setText(IDlab.read())
                print('文件./gaokong/answer/IDlab/' + str(self.n) + '.txt创建成功!')
          

Part5 单选框事件

通过单选框控制高空作业与日常施工
并通过读取txt文件内容进行判别
日常施工:未戴头盔报警
高空作业:未戴头盔或未戴安全带都报警

		#单选框
        self.ui.highwork.toggled.connect(self.highwork)
        self.ui.dailywork.toggled.connect(self.dailywork)
        if self.ui.highwork.isChecked():
            self.highwork()
        elif self.ui.dailywork.isChecked():
            self.dailywork()

    # 日常施工:未戴头盔报警
    def dailywork(self):
        # 成员显示
        try:
            with open('./gaokong/answer/GUItxt/' + str(self.n) + '.txt', 'r', encoding='utf-8') as file:
                line1 = file.readline()  # 以行的形式进行读取文件
                line2 = linecache.getline('./gaokong/answer/GUItxt/' + str(self.n) + '.txt', 2)
                line3 = linecache.getline('./gaokong/answer/GUItxt/' + str(self.n) + '.txt', 3)
                line4 = linecache.getline('./gaokong/answer/GUItxt/' + str(self.n) + '.txt', 4)
                self.dailyjudge(self.ui.check1, line1)
                self.dailyjudge(self.ui.check2, line2)
                self.dailyjudge(self.ui.check3, line3)
                self.dailyjudge(self.ui.check4, line4)
        except FileNotFoundError:
            with open('./gaokong/answer/GUItxt/' + str(self.n) + '.txt', 'a+', encoding='utf-8') as file:
                self.ui.check1.setText(file.read())
                print('文件./gaokong/answer/GUItxt/' + str(self.n) + '.txt创建成功!')

    def dailyjudge(self, ck, line):
        file = open('./gaokong/answer/GUItxt/' + str(self.n) + '.txt', 'r', encoding='utf-8')
        list1 = []
        request = "已戴头盔"
        # 成员1显示
        a = line.split()
        b = a[0:1]  # 这是选取需要读取的位数
        list1.append(b)
        for i in list1:
            file.seek(0)  # 指针定位置首部
            if request in str(i):
                # print(True)
                ck.setText(line)
            else:
                # print(False)
                ck.setText("<font color='red'>" + line)

    # 高空作业:未戴头盔或未戴安全带都报警
    def highwork(self):
        # 成员显示
        try:
            with open('./gaokong/answer/GUItxt/' + str(self.n) + '.txt', 'r', encoding='utf-8') as file:
                line1 = file.readline()  # 以行的形式进行读取文件
                line2 = linecache.getline('./gaokong/answer/GUItxt/' + str(self.n) + '.txt', 2)
                line3 = linecache.getline('./gaokong/answer/GUItxt/' + str(self.n) + '.txt', 3)
                line4 = linecache.getline('./gaokong/answer/GUItxt/' + str(self.n) + '.txt', 4)
                self.highjudge(self.ui.check1, line1)
                self.highjudge(self.ui.check2, line2)
                self.highjudge(self.ui.check3, line3)
                self.highjudge(self.ui.check4, line4)
        except FileNotFoundError:
            with open('./gaokong/answer/GUItxt/' + str(self.n) + '.txt', 'a+', encoding='utf-8') as file:
                self.ui.check1.setText(file.read())
                print('文件./gaokong/answer/GUItxt/' + str(self.n) + '.txt创建成功!')

    def highjudge(self, ck, line):
        file = open('./gaokong/answer/GUItxt/' + str(self.n) + '.txt', 'r', encoding='utf-8')
        list1 = []
        list2 = []
        request1 = "已戴头盔"
        request2 = "['已戴安全带']"
        # 成员1显示
        a = line.split()
        b = a[0:1]  # 这是选取需要读取的位数
        c = a[1:2]
        list1.append(b)
        list2.append(c)  # 将其添加在列表之中
        for i in list1:
            for j in list2:
                file.seek(0)  # 指针定位置首部
                if request1 in str(i) and str(j) in request2:
                    # print(True)
                    ck.setText(line)
                else:
                    # print(False)
                    ck.setText("<font color='red'>" + line)

Part6 多窗口成员捕捉事件

通过逐帧读取成员捕捉jpg文件实现查看人员效果

    def slot1(self):
        win2.show()
class SecondWindow(QMainWindow):
    def __init__(self, parent=None):
        super(SecondWindow, self).__init__(parent)
        self.ui = u2.Ui_Form()
        self.ui.setupUi(self)
        self.n = 3
        self.initUI()

    def initUI(self):
        self.setWindowTitle("成员捕捉1")
        self.resize(400, 300)
        self.lblpic = QLabel(self)
        self.lblpic.resize(180, 260)
        self.lblpic.move(self.width() / 2 - self.lblpic.width() / 2, self.height() / 2 - self.lblpic.height() / 2)
        self.lblpic.setScaledContents(True)

        timer1 = QTimer(self)
        timer1.timeout.connect(self.timer_TimeOut)
        timer1.start(50)

    def timer_TimeOut(self):
        path_txt_num1 = glob.glob('./gaokong/answer/crop/img_1/1_*.jpg')
        self.n += 1
        if self.n > len(path_txt_num1):
            self.n = 3
        self.pm = QPixmap('./gaokong/answer/crop/img_1/1_' + str(self.n) + ".jpg")
        self.lblpic.setPixmap(self.pm)
        
if __name__ == '__main__':
    app = QApplication(sys.argv)
    win = MainWindow()
    app.setStyleSheet(qdarkstyle.load_stylesheet())
    win2 = SecondWindow()
    win.show()
    sys.exit(app.exec_())

Part7 完整UIdisplay.py代码

# UI可视化界面

import sys
import qdarkstyle
from PyQt5.QtWidgets import QApplication, QWidget, QTextEdit, QVBoxLayout, QPushButton, QMainWindow, QFileDialog, \
    QTextBrowser, QLabel, QRadioButton
from PyQt5.QtMultimedia import QMediaContent, QMediaPlayer
from PyQt5 import uic, QtWidgets, QtGui
from PyQt5.QtCore import QTimer
from PyQt5.QtGui import QPixmap
from UIwindow import Ui_MainWindow
import UIwindow as u1
import SecondWindow as u2
import ThirdWindow as u3
import FourthWindow as u4
import glob
import cv2
import linecache


class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.ui = u1.Ui_MainWindow()
        self.ui.setupUi(self)
        self.setWindowTitle("工厂安全状态检测与人员跟踪")
        self.resize(1466, 850)
        self.n = 1
        self.cap = cv2.VideoCapture(str('./gaokong/高空作业4.avi'))
        self.timer1 = QTimer(self)
        self.timer1.timeout.connect(self.timer_TimeOut)
        self.initUI()

    def initUI(self):
        # 视频播放
        self.lblpic = QLabel(self)
        self.lblpic.resize(768, 432)
        self.lblpic.move(696, self.height() / 2 - self.lblpic.height() / 2)
        self.lblpic.setScaledContents(True)
        # 按钮事件
        self.ui.openvideo.clicked.connect(self.timestart)
        self.ui.pausevideo.clicked.connect(self.timepause)

    def timestart(self):
        self.timer1.start(10)  # 单位为毫秒

    def timepause(self):
        self.timer1.stop()

    def timer_TimeOut(self):
        frame_count = self.cap.get(cv2.CAP_PROP_FRAME_COUNT) #视频帧数
        # print(frame_count)
        self.n += 1
        if self.n > frame_count:
            self.n = 1
            self.timer1.stop()
            self.cap = cv2.VideoCapture(str('./gaokong/高空作业4.avi'))
        # 视频txt帧播放
        ret, frame = self.cap.read()
        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        img = QtGui.QImage(frame, frame.shape[1], frame.shape[0], QtGui.QImage.Format_RGB888)
        self.pm = QPixmap.fromImage(img)
        self.lblpic.setPixmap(self.pm)

        font = QtGui.QFont()
        font.setPointSize(25)
        font1 = QtGui.QFont()
        font1.setPointSize(20)
        self.ui.check1.setFont(font1)
        self.ui.check2.setFont(font1)
        self.ui.check3.setFont(font1)
        self.ui.check4.setFont(font1)
        # 视频出现过的总人数
        txtcount = open('./gaokong/answer/txtcount/' + str(self.n) + '.txt', 'r', encoding='utf-8')
        self.ui.txtcount.setText(txtcount.read())
        self.ui.txtcount.setFont(font)
        # 当前画面出现人数
        txti = open('./gaokong/answer/txti/' + str(self.n) + '.txt', 'r', encoding='utf-8')
        self.ui.txti.setText(txti.read())
        self.ui.txti.setFont(font)
        # 视频画面中出现人员姓名及位置
        try:
            with open('./gaokong/answer/IDlab/' + str(self.n) + '.txt', 'r', encoding='gbk') as IDlab:
                self.ui.textBrowser.setText(IDlab.read())
        except FileNotFoundError:
            with open('./gaokong/answer/IDlab/' + str(self.n) + '.txt', 'a+', encoding='gbk') as IDlab:
                self.ui.textBrowser.setText(IDlab.read())
                print('文件./gaokong/answer/IDlab/' + str(self.n) + '.txt创建成功!')
        #单选框
        self.ui.highwork.toggled.connect(self.highwork)
        self.ui.dailywork.toggled.connect(self.dailywork)
        if self.ui.highwork.isChecked():
            self.highwork()
        elif self.ui.dailywork.isChecked():
            self.dailywork()

    # 日常施工:未戴头盔报警
    def dailywork(self):
        # 成员显示
        try:
            with open('./gaokong/answer/GUItxt/' + str(self.n) + '.txt', 'r', encoding='utf-8') as file:
                line1 = file.readline()  # 以行的形式进行读取文件
                line2 = linecache.getline('./gaokong/answer/GUItxt/' + str(self.n) + '.txt', 2)
                line3 = linecache.getline('./gaokong/answer/GUItxt/' + str(self.n) + '.txt', 3)
                line4 = linecache.getline('./gaokong/answer/GUItxt/' + str(self.n) + '.txt', 4)
                self.dailyjudge(self.ui.check1, line1)
                self.dailyjudge(self.ui.check2, line2)
                self.dailyjudge(self.ui.check3, line3)
                self.dailyjudge(self.ui.check4, line4)
        except FileNotFoundError:
            with open('./gaokong/answer/GUItxt/' + str(self.n) + '.txt', 'a+', encoding='utf-8') as file:
                self.ui.check1.setText(file.read())
                print('文件./gaokong/answer/GUItxt/' + str(self.n) + '.txt创建成功!')

    def dailyjudge(self, ck, line):
        file = open('./gaokong/answer/GUItxt/' + str(self.n) + '.txt', 'r', encoding='utf-8')
        list1 = []
        request = "已戴头盔"
        # 成员1显示
        a = line.split()
        b = a[0:1]  # 这是选取需要读取的位数
        list1.append(b)
        for i in list1:
            file.seek(0)  # 指针定位置首部
            if request in str(i):
                # print(True)
                ck.setText(line)
            else:
                # print(False)
                ck.setText("<font color='red'>" + line)

    # 高空作业:未戴头盔或未戴安全带都报警
    def highwork(self):
        # 成员显示
        try:
            with open('./gaokong/answer/GUItxt/' + str(self.n) + '.txt', 'r', encoding='utf-8') as file:
                line1 = file.readline()  # 以行的形式进行读取文件
                line2 = linecache.getline('./gaokong/answer/GUItxt/' + str(self.n) + '.txt', 2)
                line3 = linecache.getline('./gaokong/answer/GUItxt/' + str(self.n) + '.txt', 3)
                line4 = linecache.getline('./gaokong/answer/GUItxt/' + str(self.n) + '.txt', 4)
                self.highjudge(self.ui.check1, line1)
                self.highjudge(self.ui.check2, line2)
                self.highjudge(self.ui.check3, line3)
                self.highjudge(self.ui.check4, line4)
        except FileNotFoundError:
            with open('./gaokong/answer/GUItxt/' + str(self.n) + '.txt', 'a+', encoding='utf-8') as file:
                self.ui.check1.setText(file.read())
                print('文件./gaokong/answer/GUItxt/' + str(self.n) + '.txt创建成功!')

    def highjudge(self, ck, line):
        file = open('./gaokong/answer/GUItxt/' + str(self.n) + '.txt', 'r', encoding='utf-8')
        list1 = []
        list2 = []
        request1 = "已戴头盔"
        request2 = "['已戴安全带']"
        # 成员1显示
        a = line.split()
        b = a[0:1]  # 这是选取需要读取的位数
        c = a[1:2]
        list1.append(b)
        list2.append(c)  # 将其添加在列表之中
        for i in list1:
            for j in list2:
                file.seek(0)  # 指针定位置首部
                if request1 in str(i) and str(j) in request2:
                    # print(True)
                    ck.setText(line)
                else:
                    # print(False)
                    ck.setText("<font color='red'>" + line)

    def slot1(self):
        win2.show()

    def slot2(self):
        win3.show()

    def slot3(self):
        win4.show()

    def slot4(self):
        win5.show()


class SecondWindow(QMainWindow):
    def __init__(self, parent=None):
        super(SecondWindow, self).__init__(parent)
        self.ui = u2.Ui_Form()
        self.ui.setupUi(self)
        self.n = 3
        self.initUI()

    def initUI(self):
        self.setWindowTitle("成员捕捉1")
        self.resize(400, 300)
        self.lblpic = QLabel(self)
        self.lblpic.resize(180, 260)
        self.lblpic.move(self.width() / 2 - self.lblpic.width() / 2, self.height() / 2 - self.lblpic.height() / 2)
        self.lblpic.setScaledContents(True)

        timer1 = QTimer(self)
        timer1.timeout.connect(self.timer_TimeOut)
        timer1.start(50)

    def timer_TimeOut(self):
        path_txt_num1 = glob.glob('./gaokong/answer/crop/img_1/1_*.jpg')
        self.n += 1
        if self.n > len(path_txt_num1):
            self.n = 3
        self.pm = QPixmap('./gaokong/answer/crop/img_1/1_' + str(self.n) + ".jpg")
        self.lblpic.setPixmap(self.pm)


class ThirdWindow(QMainWindow):
    def __init__(self, parent=None):
        super(ThirdWindow, self).__init__(parent)
        self.ui = u3.Ui_Form()
        self.ui.setupUi(self)
        self.n = 3
        self.initUI()

    def initUI(self):
        self.setWindowTitle("成员捕捉2")
        self.resize(400, 300)
        self.lblpic = QLabel(self)
        self.lblpic.resize(180, 260)
        self.lblpic.move(self.width() / 2 - self.lblpic.width() / 2, self.height() / 2 - self.lblpic.height() / 2)
        self.lblpic.setScaledContents(True)

        timer1 = QTimer(self)
        timer1.timeout.connect(self.timer_TimeOut)
        timer1.start(50)

    def timer_TimeOut(self):
        path_txt_num = glob.glob('./gaokong/answer/crop/img_2/2_*.jpg')
        self.n += 1
        if self.n > len(path_txt_num):
            self.n = 3
        self.pm = QPixmap('./gaokong/answer/crop/img_2/2_' + str(self.n) + ".jpg")
        self.lblpic.setPixmap(self.pm)


class FourthWindow(QMainWindow):
    def __init__(self, parent=None):
        super(FourthWindow, self).__init__(parent)
        self.ui = u4.Ui_Form()
        self.ui.setupUi(self)
        self.n = 3
        self.initUI()

    def initUI(self):
        self.setWindowTitle("成员捕捉3")
        self.resize(400, 300)
        self.lblpic = QLabel(self)
        self.lblpic.resize(180, 260)
        self.lblpic.move(self.width() / 2 - self.lblpic.width() / 2, self.height() / 2 - self.lblpic.height() / 2)
        self.lblpic.setScaledContents(True)

        timer1 = QTimer(self)
        timer1.timeout.connect(self.timer_TimeOut)
        timer1.start(50)

    def timer_TimeOut(self):
        path_txt_num = glob.glob('./gaokong/answer/crop/img_3/3_*.jpg')
        self.n += 1
        if self.n > len(path_txt_num):
            self.n = 3
        self.pm = QPixmap('./gaokong/answer/crop/img_3/3_' + str(self.n) + ".jpg")
        self.lblpic.setPixmap(self.pm)


class FifthWindow(QMainWindow):
    def __init__(self, parent=None):
        super(FifthWindow, self).__init__(parent)
        self.ui = u4.Ui_Form()
        self.ui.setupUi(self)
        self.n = 3
        self.initUI()

    def initUI(self):
        self.setWindowTitle("成员捕捉4")
        self.resize(400, 300)
        self.lblpic = QLabel(self)
        self.lblpic.resize(180, 260)
        self.lblpic.move(self.width() / 2 - self.lblpic.width() / 2, self.height() / 2 - self.lblpic.height() / 2)
        self.lblpic.setScaledContents(True)

        timer1 = QTimer(self)
        timer1.timeout.connect(self.timer_TimeOut)
        timer1.start(50)

    def timer_TimeOut(self):
        path_txt_num = glob.glob('./gaokong/answer/crop/img_4/4_*.jpg')
        self.n += 1
        if self.n > len(path_txt_num):
            self.n = 3
        self.pm = QPixmap('./gaokong/answer/crop/img_4/4_' + str(self.n) + ".jpg")
        self.lblpic.setPixmap(self.pm)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    win = MainWindow()
    app.setStyleSheet(qdarkstyle.load_stylesheet())
    win2 = SecondWindow()
    win3 = ThirdWindow()
    win4 = FourthWindow()
    win5 = FifthWindow()
    win.show()
    sys.exit(app.exec_())

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐