Python 未使用不同类中的信号和插槽PyQt5定义Url
我正在尝试使用线程并行运行带有参数的视频 因此,当我点击SD按钮时,它会激活TP1和TP2按钮,每个按钮都有一个不同的Url 我想显示视频并启动ProgressBar,最后显示结果Python 未使用不同类中的信号和插槽PyQt5定义Url,python,pyqt,pyqt5,signals-slots,qthread,Python,Pyqt,Pyqt5,Signals Slots,Qthread,我正在尝试使用线程并行运行带有参数的视频 因此,当我点击SD按钮时,它会激活TP1和TP2按钮,每个按钮都有一个不同的Url 我想显示视频并启动ProgressBar,最后显示结果 from multiprocessing import Process import sys import json import shlex import threading import subprocess import webbrowser from QLed import QLed from functo
from multiprocessing import Process
import sys
import json
import shlex
import threading
import subprocess
import webbrowser
from QLed import QLed
from functools import partial
from PyQt5.QtGui import QColor,QFont
from PyQt5.QtGui import QIcon, QPixmap
from PyQt5.QtGui import QPainter, QPen
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtGui import QPainter, QColor, QPen
from PyQt5.QtMultimedia import QMediaContent, QMediaPlayer
from PyQt5.QtCore import QDir, Qt, QUrl, QSize, QPoint, QTimer
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QMainWindow
from PyQt5 import QtCore, QtGui, QtWidgets, QtMultimedia, QtMultimediaWidgets
from PyQt5.QtWidgets import (QWidget, QPushButton, QApplication,QGridLayout, QLCDNumber)
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QVBoxLayout, QGridLayout, QLCDNumber
class Analyzer(QtCore.QObject):
result_ready = QtCore.pyqtSignal(object)
def do_work(self, myurl):
cmd = "ffprobe -v quiet -print_format json -show_streams"
args = shlex.split(cmd)
args.append(myurl)
ffprobeOutput = subprocess.check_output(args).decode('utf-8')
ffprobeOutput = json.loads(ffprobeOutput)
result = ffprobeOutput['streams'][0]
self.result_ready.emit(result)
class MainProg(QtWidgets.QMainWindow):
def __init__(self):
super(MainProg, self).__init__()
self.resize(870, 525)
self.centralwidget = QtWidgets.QWidget(self)
self.centralwidget.setObjectName("centralwidget")
############################ The Viedeo and frame ######
self.frame = QtWidgets.QFrame(self)
self.frame.setGeometry(QtCore.QRect(450, 40, 391, 291))
self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
self.mediaPlayer = QtMultimedia.QMediaPlayer(self.frame)
self.viewer1 = QtMultimediaWidgets.QVideoWidget(self.frame)
self.mediaPlayer.setVideoOutput(self.viewer1)
layout1 = QtWidgets.QGridLayout(self.frame)
layout1.addWidget(self.viewer1, 0, 0, 1, 2)
#############################################################
self.progressBar = QtWidgets.QProgressBar(self.centralwidget)
self.progressBar.setGeometry(QtCore.QRect(110, 470, 143, 25))
self.progressBar.setProperty("value", 0)
self.progressBar.setTextVisible(True)
self.lcd = QtWidgets.QLCDNumber(self.centralwidget)
self.lcd.setGeometry(QtCore.QRect(220, 50, 146, 50))
self.lcd1 = QtWidgets.QLCDNumber(self.centralwidget)
self.lcd1.setGeometry(QtCore.QRect(220, 100, 146, 50))
self.lcd2 = QtWidgets.QLCDNumber(self.centralwidget)
self.lcd2.setGeometry(QtCore.QRect(220, 150, 146, 50))
self.lcd3 = QtWidgets.QLCDNumber(self.centralwidget)
self.lcd3.setGeometry(QtCore.QRect(220, 200, 146, 50))
self.lcd4 = QtWidgets.QLCDNumber(self.centralwidget)
self.lcd4.setGeometry(QtCore.QRect(220, 250, 146, 50))
self.lcd5 = QtWidgets.QLCDNumber(self.centralwidget)
self.lcd5.setGeometry(QtCore.QRect(220, 300, 146, 50))
self.lcd6 = QtWidgets.QLCDNumber(self.centralwidget)
self.lcd6.setGeometry(QtCore.QRect(220, 350, 146, 50))
self.txtt = QtWidgets.QLabel(self.centralwidget)
self.txtt.setFont(QFont('Arial', 12))
self.txtt.setGeometry(QtCore.QRect(20, 0, 300, 400))
self.txtt.setText("Video"
"\nCode Name .................."
"\n\nHorizont........................"
"\n\nVertical.........................."
"\n\nDisplay Aspect Ratio......"
"\n\nRefrence........................."
"\n\nB frames........................."
"\n\nStart Bits......................."
"\n\nSample Aspect ratio......."
"\n\nBit Rate.........................")
self.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(self)
self.statusbar.setObjectName("statusbar")
self.setStatusBar(self.statusbar)
#########################The buttons#################################
self.AASD = QtWidgets.QToolButton(self)
self.AASD.setGeometry(QtCore.QRect(140, 20, 31, 32))
self.AASD.setObjectName("AASD")
self.AASD.setText("SD")
self.AASD.clicked.connect(self.funcchoos)
QTimer.singleShot(5000, lambda: self.AASD.setDisabled(False))
self.Testpunk1 = QtWidgets.QToolButton(self)
self.Testpunk1.setGeometry(QtCore.QRect(150, 400, 31, 32))
self.Testpunk2 = QtWidgets.QToolButton(self)
self.Testpunk2.setGeometry(QtCore.QRect(150, 430, 31, 32))
self.Testpunk1.setText("TP1")
self.Testpunk2.setText("TP2")
self.Testpunk1.setObjectName("TP1")
self.Testpunk2.setObjectName("TP2")
self.Tp1 = QLed(self, onColour=QLed.Orange, shape=QLed.Circle)
self.Tp1.setGeometry(QtCore.QRect(185, 415, 25, 25))
self.Tp1.value = False
########################### the functions############################
def funcchoos (self):
QtCore.QTimer.singleShot(500, self.TPLed) # Using timer as QLed uses it in its tests
if self.sender().objectName() == "AASD":
self.Testpunk1.clicked.connect(self.MyUrl)
self.Testpunk2.clicked.connect(self.MyUrl)
return
def MyUrl(self):
TP1 = "293.168.1.6:1115"
TP2 = "239.168.1.7:1116"
if self.sender().objectName() == "TP1":
myurl = TP1
print("TP1 is playing")
self.dep3(myurl)
return
if self.sender().objectName() == "TP2":
myurl = TP2
self.dep3(myurl)
print(myurl)
print("TP2 is playing")
return
##############################################################
def TPLed(self):
self.Tp1.setValue(True) # the LED ON code
#########################################################################
def dep3(self,myurl):
# set progress bar to undetermined state and disable button
self.progressBar.setRange(0,0)
self.Testpunk1.setEnabled(False)
self.mediaPlayer.setMedia(QMediaContent(QUrl(myurl)))
self.mediaPlayer.play()
# create thread for doing heavy work
self.thread = QtCore.QThread()
self.worker = Analyzer()
self.worker.moveToThread(self.thread)
self.thread.started.connect(self.worker.do_work(myurl))
self.thread.finished.connect(self.worker.deleteLater)
self.worker.result_ready.connect(self.process_result)
self.worker.result_ready.connect(self.worker.do_work(myurl))
self.thread.start()
def process_result(self, result):
codec_name = result['codec_name']
width = result['width']
height = result['height']
display_aspect_ratio = result['display_aspect_ratio']
sample_aspect_ratio = result['sample_aspect_ratio']
refs = result['refs']
has_b_frames = result['has_b_frames']
self.lcd.display(has_b_frames)
self.lcd1.display(codec_name)
self.lcd2.display(width)
self.lcd3.display(height)
self.lcd4.display(display_aspect_ratio)
self.lcd5.display(sample_aspect_ratio)
self.lcd6.display(refs)
# reset progress bar and push button
self.progressBar.setRange(0,100)
self.progressBar.setValue(100)
self.pushButton.setEnabled(True)
print("done!!")
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
player = MainProg()
player.show()
sys.exit(app.exec_())
主要问题是,当您使用:
foo.signal.connect(function(args))
相等于
value = function(args)
foo.signal.connect(value)
这会导致错误,因为connect需要一个可调用的,而在您的情况下,值是None导致错误
通常的解决方案是使用lambda或partials,但第一种方法会导致函数在主线程中执行,因为它是在该线程中调用的,因此必须放弃它,而partials只添加参数
- 拉姆达:
- 部分函数
从functools导入部分
导入json
导入shlex
导入子流程
导入系统
从QLed导入QLed
从PyQt5导入QtCore、QtGui、QtWidgets、QtMultimedia、QtMultimediaWidgets
类分析器(QtCore.QObject):
结果_ready=QtCore.pyqtSignal(对象)
@QtCore.pyqtSlot(str)
def do_work(self,myurl):
cmd=“ffprobe-v quiet-print\u format json-show\u streams”
args=shlex.split(cmd)
args.append(myurl)
ffprobeOutput=子进程。检查输出(args)。解码(“utf-8”)
ffprobeOutput=json.load(ffprobeOutput)
结果=ffprobeOutput[“流”][0]
self.result\u ready.emit(结果)
类MainProg(QtWidgets.QMainWindow):
def uuu init uuu(self,parent=None):
超级(MainProg,self)。\uuuu初始化(父级)
self.setFont(QtGui.QFont(“Arial”,12))
central_widget=qtwidts.QWidget()
self.setCentralWidget(中心窗口小部件)
hlay=qtwidts.QHBoxLayout(中心小部件)
left_widget=qtwidts.QWidget()
self.mediaPlayer=qtmedia.QMediaPlayer()
self.video_widget=qtmediawidgets.QVideoWidget()
self.video_widget.setContentsMargins(30,30,30,30)
self.mediaPlayer.setVideoOutput(self.video\u小部件)
self.sd_button=qtwidts.QToolButton(text=“sd”,checkable=True)
self.sd_按钮设置固定大小(31,32)
self.code_lcd=QtWidgets.QLCDNumber()
self.horizontal_lcd=qtwidts.QLCDNumber()
self.vertical_lcd=QtWidgets.QLCDNumber()
self.display\u aspect\u ratio\u lcd=qtwidts.QLCDNumber()
self.reference_lcd=qtwidts.QLCDNumber()
self.b_frames_lcd=qtwidts.QLCDNumber()
self.start\u bits\u lcd=qtwidts.QLCDNumber()
self.sample\u aspect\u ratio\u lcd=qtwidts.QLCDNumber()
self.bit\u rate\u lcd=qtwidts.QLCDNumber()
self.tp1_button=qtwidts.QToolButton(text=“tp1”)
self.tp2_button=qtwidts.QToolButton(text=“tp2”)
self.led=QLed(self,onclour=QLed.Orange,shape=QLed.Circle)
self.progressbar=qtwidts.QProgressBar()
用于液晶显示器(
self.code_液晶显示器,
自聚焦液晶显示器,
自立式液晶显示器,
自显示\u纵横比\u lcd,
自参考液晶显示器,
self.b_frames_lcd,
自启动\u位\u lcd,
自采样\u纵横比\u lcd,
自比特率液晶显示器,
):
lcd.setFixedSize(146,50)
hlay.addWidget(左_小部件)
hlay.addWidget(self.video\u小部件,拉伸=1)
lay=qtwidts.QGridLayout(左_小部件)
铺设.设置垂直间距(5)
对于枚举中的i,(文本,小部件)(
拉链(
(
“视频”,
“编解码器名称:”,
“水平:”,
“垂直:”,
“显示纵横比:”,
“引用:”,
“B帧:”,
“起始位:”,
“样本纵横比:”,
“比特率:”,
),
(
self.sd_按钮,
self.code_液晶显示器,
自聚焦液晶显示器,
自立式液晶显示器,
自显示\u纵横比\u lcd,
自参考液晶显示器,
self.b_frames_lcd,
自启动\u位\u lcd,
自采样\u纵横比\u lcd,
自比特率液晶显示器,
),
)
):
label=qtwidts.QLabel(文本)
lay.addWidget(标签,i,0)
lay.addWidget(widget,i,1,alignment=QtCore.Qt.AlignCenter)
vlay=qtwidts.QVBoxLayout()
vlay.addWidget(self.tp1_按钮)
vlay.addWidget(self.tp2_按钮)
hlay2=qtwidts.QHBoxLayout()
hlay2.addStretch(0)
hlay2.添加布局(vlay)
hlay2.addWidget(self.led)
hlay2.addStretch(0)
lay.addLayout(hlay2,lay.rowCount(),0,1,2)
lay.addWidget(self.progressbar,lay.rowCount(),0,1,2)
lay.setRowStretch(lay.rowCount(),1)
自我调整大小(960480)
self.sd_按钮。切换。连接(self.led.setValue)
self.tp1_按钮。单击。连接(self.on_tp_单击)
self.tp2_按钮。单击。连接(self.on_tp_单击)
self.current_按钮=无
thread=QtCore.QThread(self)
thread.start()
self.worker=Analyzer()
self.worker.moveToThread(线程)
self.worker.result\u ready.connect(self.process\u result)
@QtCore.pyqtSlot()
已单击(自身)上的def:
如果self.sd_button.isChecked():
URL\u映射={
self.tp1_按钮:“293.168.1.6:1115”,
self.tp2_按钮:“239.168.1.7:1116”,
}
url=url
foo.signal.connect(lambda *_, args=args : function(args))
foo.signal.connect(functools.partial(function, args))