正在处理较长的Python函数时显示请稍候消息

问题描述 投票:0回答:1

我有一个分析视频文件的元数据并将其显示在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_())
python time pyqt pyqt5
1个回答
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!!")

© www.soinside.com 2019 - 2024. All rights reserved.