在执行长Python功能时显示“请稍候”消息

时间:2019-11-28 09:06:28

标签: python time pyqt pyqt5

我有一个代码,可以分析视频文件的元数据并将其显示在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_())

1 个答案:

答案 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!!")