PyQt5 UDP视频播放器按钮状态重置功能实现求助
解决PyQt5 UDP视频播放器按钮状态重置与视频停止问题
我来帮你搞定这个问题!你需要实现的核心是:当点击新的SD类或Source类按钮时,自动重置之前所有按钮的选中状态、停止当前播放的视频,并只激活对应类别的TP按钮,避免出现多个按钮同时启用的混乱情况。下面是具体的实现方案和修改后的完整代码:
实现思路
- 按钮分组管理:把SD类按钮、Source类按钮、TP按钮分别归类到列表中,方便后续批量操作状态。
- 统一重置函数:编写一个专门的函数,负责停止视频、重置所有按钮状态、关闭指示灯、清空节目名称。
- 绑定按钮点击事件:给每个SD/Source按钮绑定点击事件,触发时先执行重置,再激活对应组的TP按钮并标记自己为选中状态。
- 初始化TP按钮状态:默认所有TP按钮都是禁用的,只有点击对应类别按钮后才启用。
修改后的完整代码
import vlc import os import sys import threading from QLed import QLed from functools import partial from PyQt5.QtGui import QColor, QFont from PyQt5.QtGui import QPainter, QPen from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5.QtCore import QDir, Qt, QUrl, QSize, QPoint, QTimer from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QMainWindow from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QVBoxLayout, QGridLayout, QLCDNumber class MainProg(QtWidgets.QMainWindow): def __init__(self, parent=None): super(MainProg, self).__init__(parent) self.setObjectName("MainWindow") self.setFixedSize(1280, 768) self.setStyleSheet("") self.setWindowTitle("video player ") self.instance = vlc.Instance() self.mediaplayer = self.instance.media_player_new() ################# The Test Points LEDs ###################### self.TPL1 = QLed(self, onColour=QLed.Orange, shape=QLed.Round) self.TPL1.setGeometry(QtCore.QRect(190, 500, 35, 25)) self.TPL3 = QLed(self, onColour=QLed.Orange, shape=QLed.Round) self.TPL3.setGeometry(QtCore.QRect(440, 525, 35, 25)) ######################## Test Points Geo ############################################## self.Testpunk1 = QtWidgets.QPushButton(self) self.Testpunk1.setGeometry(QtCore.QRect(190, 460, 31, 31)) self.Testpunk1.setObjectName("TP1") self.Testpunk2 = QtWidgets.QPushButton(self) self.Testpunk2.setGeometry(QtCore.QRect(190, 530, 31, 31)) self.Testpunk2.setObjectName("TP2") self.Testpunk5 = QtWidgets.QPushButton(self) self.Testpunk5.setGeometry(QtCore.QRect(440, 490, 31, 31)) self.Testpunk5.setObjectName("TP5") self.Testpunk6 = QtWidgets.QPushButton(self) self.Testpunk6.setGeometry(QtCore.QRect(440, 550, 31, 31)) self.Testpunk6.setObjectName("TP6") # 初始化TP按钮为禁用状态 self.Testpunk1.setEnabled(False) self.Testpunk2.setEnabled(False) self.Testpunk5.setEnabled(False) self.Testpunk6.setEnabled(False) ##########set text self.Testpunk1.setText(("TP1")) self.Testpunk2.setText(("TP2")) self.Testpunk5.setText(("TP5")) self.Testpunk6.setText(("TP6")) ############################ The Video and frame ################################# self.videoframe = QtWidgets.QFrame(self) self.videoframe.setGeometry(QtCore.QRect(850, 40, 391, 291)) self.videoframe.setFrameShape(QtWidgets.QFrame.Box) self.videoframe.setFrameShadow(QtWidgets.QFrame.Raised) self.vboxlayout = QVBoxLayout() self.vboxlayout.addWidget(self.videoframe) self.mediaplayer.set_hwnd(int(self.videoframe.winId())) ######################################################################################## ########################## SD and HD buttons############################################ self.EspSD = QtWidgets.QToolButton(self, text="SD1", checkable=True) self.EspSD.setGeometry(QtCore.QRect(140, 170, 31, 32)) self.EspSD.setObjectName("SD") self.DeuSD = QtWidgets.QToolButton(self, text="SD2", checkable=True) self.DeuSD.setGeometry(QtCore.QRect(140, 220, 31, 32)) self.DeuSD.setObjectName("DeSD") self.DeupSD = QtWidgets.QToolButton(self, text="SD3", checkable=True) self.DeupSD.setGeometry(QtCore.QRect(140, 270, 31, 32)) self.DeupSD.setObjectName("DpSD") ##########################source buttons############################################ self.IntS = QtWidgets.QToolButton(self, text="Source5", checkable=True) self.IntS.setGeometry(QtCore.QRect(240, 170, 65, 32)) self.IntS.setObjectName("5") self.AstD = QtWidgets.QToolButton(self, text="Source6", checkable=True) self.AstD.setGeometry(QtCore.QRect(240, 220, 65, 32)) self.AstD.setObjectName("6") self.IntSdep = QtWidgets.QToolButton(self, text="Source7", checkable=True) self.IntSdep.setGeometry(QtCore.QRect(240, 270, 65, 32)) self.IntSdep.setObjectName("7") ################################### The Main Window Labels ############################ self.CurrentPro = QtWidgets.QLabel(self) self.CurrentPro.setFont(QFont('Arial', 10)) self.CurrentPro.setGeometry(QtCore.QRect(580, 55, 140, 35)) self.CurrentPro.setText("Current Program :") self.CurrentProL = QtWidgets.QLabel(self) self.CurrentProL.setFont(QFont('Arial', 10)) self.CurrentProL.setGeometry(QtCore.QRect(690, 55, 155, 35)) # 按钮分组:方便批量管理状态 self.sd_buttons = [self.EspSD, self.DeuSD, self.DeupSD] self.source_buttons = [self.IntS, self.AstD, self.IntSdep] self.tp_enc_buttons = [self.Testpunk1, self.Testpunk2] self.tp_mux_buttons = [self.Testpunk5, self.Testpunk6] #################################### 绑定按钮点击事件 ###################################### # TP按钮点击事件 self.Testpunk1.clicked.connect(self.on_tp_clicked_Enc) self.Testpunk2.clicked.connect(self.on_tp_clicked_Enc) self.Testpunk5.clicked.connect(self.on_tp_clicked_Mux) self.Testpunk6.clicked.connect(self.on_tp_clicked_Mux) # SD按钮点击事件 self.EspSD.clicked.connect(partial(self.on_sd_source_clicked, is_sd=True, button=self.EspSD)) self.DeuSD.clicked.connect(partial(self.on_sd_source_clicked, is_sd=True, button=self.DeuSD)) self.DeupSD.clicked.connect(partial(self.on_sd_source_clicked, is_sd=True, button=self.DeupSD)) # Source按钮点击事件 self.IntS.clicked.connect(partial(self.on_sd_source_clicked, is_sd=False, button=self.IntS)) self.AstD.clicked.connect(partial(self.on_sd_source_clicked, is_sd=False, button=self.AstD)) self.IntSdep.clicked.connect(partial(self.on_sd_source_clicked, is_sd=False, button=self.IntSdep)) def reset_all_states(self): """重置所有状态:停止视频、重置按钮、关闭LED、清空节目名""" # 停止当前播放的视频 if self.mediaplayer.is_playing(): self.mediaplayer.stop() # 取消所有SD和Source按钮的选中状态 for btn in self.sd_buttons + self.source_buttons: btn.setChecked(False) # 禁用所有TP按钮 for btn in self.tp_enc_buttons + self.tp_mux_buttons: btn.setEnabled(False) # 关闭LED指示灯 self.TPL1.setValue(False) self.TPL3.setValue(False) # 清空节目名称标签 self.CurrentProL.setText("") def on_sd_source_clicked(self, is_sd, button): """处理SD或Source按钮的点击事件""" # 先重置所有状态 self.reset_all_states() # 标记当前按钮为选中状态 button.setChecked(True) # 激活对应组的TP按钮 if is_sd: for btn in self.tp_enc_buttons: btn.setEnabled(True) else: for btn in self.tp_mux_buttons: btn.setEnabled(True) def on_tp_clicked_Enc(self): self.TPL1.setValue(True) if self.EspSD.isChecked(): urls_map = { self.Testpunk1: "udp://@239.168.1.6:1113", self.Testpunk2: "udp://@239.168.1.7:1117", } url = urls_map.get(self.sender(), "") if url: self.play(url) self.CurrentProL.setText("Program4") elif self.DeuSD.isChecked(): urls_map = { self.Testpunk1: "udp://@239.168.1.6:1123", self.Testpunk2: "udp://@239.168.1.7:1127", } url = urls_map.get(self.sender(), "") if url: self.play(url) self.CurrentProL.setText("Program5") elif self.DeupSD.isChecked(): urls_map = { self.Testpunk1: "udp://@239.168.1.6:1121", self.Testpunk2: "udp://@239.168.1.7:1125", } url = urls_map.get(self.sender(), "") if url: self.play(url) self.CurrentProL.setText("Program6") @QtCore.pyqtSlot() def on_tp_clicked_Mux(self): self.TPL3.setValue(True) if self.IntS.isChecked(): urls_map = { self.Testpunk5: "udp://@239.168.2.6:2113", self.Testpunk6: "udp://@239.168.2.7:2123", } url = urls_map.get(self.sender(), "") if url: self.play(url) self.CurrentProL.setText("Program3 Source3") elif self.AstD.isChecked(): urls_map = { self.Testpunk5: "udp://@239.168.2.6:2117", self.Testpunk6: "udp://@239.168.2.7:2127", } url = urls_map.get(self.sender(), "") if url: self.play(url) self.CurrentProL.setText("Program4 Source4") elif self.IntSdep.isChecked(): urls_map = { self.Testpunk5: "udp://@239.168.2.6:2113", self.Testpunk6: "udp://@239.168.2.7:2123", } url = urls_map.get(self.sender(), "") if url: self.play(url) self.CurrentProL.setText("Program4 Source5") def play(self, url): print('the url arrived') self.media = self.instance.media_new(url) self.media.get_mrl() self.mediaplayer.set_media(self.media) print('last step before video viewing') self.mediaplayer.play() if __name__ == "__main__": import sys app = QtWidgets.QApplication(sys.argv) w = MainProg() w.show() sys.exit(app.exec_())
关键修改说明
- 按钮分组:新增了
sd_buttons、source_buttons等列表,把同类别按钮归类,方便批量操作状态。 - 重置函数:
reset_all_states函数统一处理状态重置逻辑,避免重复代码。 - SD/Source按钮事件绑定:用
partial传递参数,点击时先重置所有状态,再激活对应TP按钮。 - TP按钮初始状态:默认禁用,只有点击对应类别按钮后才启用,避免误操作。
- 优化条件判断:把TP按钮事件中的
if改为elif,避免多个条件同时触发(虽然之前逻辑也没问题,但这样更严谨)。
这样修改后,当你点击任意SD或Source按钮时,之前的视频会停止,所有按钮状态会重置,只有当前点击的按钮处于选中状态,且对应组的TP按钮会被激活,完美解决你遇到的问题!
内容的提问来源于stack exchange,提问作者user12833369
相关产品推荐
相关产品推荐

