我有一个代码,可以分析视频文件的元数据并将其显示在LCD QT小部件中
这个过程需要将近15到20秒,我想显示(请稍等)或显示进度条。
我添加了一个进度条,但它与功能无关(与它无关)。
这是我的代码:
from multiprocessing import Process
import timeit
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QMainWindow
from PyQt5.QtGui import QColor,QFont
from PyQt5 import QtCore, QtGui, QtWidgets
import subprocess
import shlex
import json
import sys
import webbrowser
import threading
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(470, 525)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
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.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(120, 430, 121, 25))
self.pushButton.setObjectName("pushButton")
self.pushButton.clicked.connect(self.dep3)
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.........................")
MainWindow.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.pushButton.setText(_translate("MainWindow", "Ratio"))
########### This is the Function that i want to calculate its time
def task1(self):
cmd = "ffprobe -v quiet -print_format json -show_streams"
args = shlex.split(cmd)
myurl="HERE YOU CAN PUT THE VIDEO STREAM OR ITS DIRECTOY"
args.append(myurl)
ffprobeOutput = subprocess.check_output(args).decode('utf-8')
ffprobeOutput = json.loads(ffprobeOutput)
codec_name = ffprobeOutput['streams'][0]['codec_name']
width = ffprobeOutput['streams'][0]['width']
height = ffprobeOutput['streams'][0]['height']
display_aspect_ratio = ffprobeOutput['streams'][0]['display_aspect_ratio']
sample_aspect_ratio = ffprobeOutput['streams'][0]['sample_aspect_ratio']
refs = ffprobeOutput['streams'][0]['refs']
has_b_frames = ffprobeOutput['streams'][0]['has_b_frames']
# start_pts = ffprobeOutput['streams'][0]['start_pts']
# bit_rate= ffprobeOutput['streams'][0]['bit_rate']
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)
# self.lcd8.display(start_pts)
# self.lcd9.display(bit_rate)
self.lcd.show()
self.lcd1.show()
self.lcd2.show()
self.lcd3.show()
self.lcd4.show()
self.lcd5.show()
self.lcd6.show()
print("done!!")
def task2(self):
self.completed = 0
while self.completed < 100:
self.completed += 0.00002
self.progressBar.setValue(self.completed)
def dep1(self):
t1 = threading.Thread(target=self.task1)
t2 = threading.Thread(target=self.task2)
t1.start()
t2.start()
t1.join()
t2.join()
def dep3(self):
d1 = threading.Thread(target=self.dep1)
d1.start()
d1.join()
pass
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
答案 0 :(得分:1)
您真的不应该从其他线程更新小部件。请改用信号和插槽来传递数据。这是一个使用QThread
和自定义工作程序类的示例。工人阶级从事实际工作。分析完成后,它会发出带有结果的信号。
# Worker class that fetches data and emits result when ready.
class Analyzer(QtCore.QObject):
result_ready = QtCore.pyqtSignal(dict)
def do_work(self):
cmd = "ffprobe -v quiet -print_format json -show_streams"
args = shlex.split(cmd)
myurl = "HERE YOU CAN PUT THE VIDEO STREAM OR ITS DIRECTOY"
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 Ui_MainWindow(object):
....
def dep3(self):
# set progress bar to undetermined state and disable button
self.progressBar.setRange(0,0)
self.pushButton.setEnabled(False)
# 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)
self.thread.finished.connect(self.worker.deleteLater)
self.worker.result_ready.connect(self.process_result)
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']
# start_pts = ffprobeOutput['streams'][0]['start_pts']
# bit_rate= ffprobeOutput['streams'][0]['bit_rate']
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!!")