如何实现QProgressBar从“忙”模式到标准进度模式的转换?

时间:2016-11-12 15:33:34

标签: multithreading qt pyqt progress-bar pyside

假设我有收集文件和稍后复制的任务。收集QProgressBar时显示一些无限的“忙”状态。之后,该过程将继续复制收集的文件并显示进度。 问题是我可以做任何一个但不能在连续过程中一起做。 Down是PySide中的一些代码,通过按QButton 1和2显示此工作,但不是连续任务。请帮忙。

The Good, the Bad and the Ugly
1966
APPROVED
Western
161
8.900000

Memento
2000
R
Mystery/Thriller
113
8.500000

所以,如果我要评论上面的两行,要按下第一个按钮启动这两个功能,进度条根本不会显示“忙碌”模式!

1 个答案:

答案 0 :(得分:2)

您应该在单独的线程中执行耗时的工作,并发出信号以更新进度。以下是基于您的示例的简单演示:

import sys, time, random
from PySide.QtGui import *
from PySide.QtCore import *

class Worker(QThread):
    progressChanged = Signal(int, int)

    def run(self):
        items = []
        count = random.randint(5, 10)
        print('collecting items...')
        while len(items) < count:
            items.append(1)
            time.sleep(.5)
        print('processing items...')
        for index, item in enumerate(items):
            self.progressChanged.emit(index, count)
            time.sleep(0.5)

class WidgetWithBar(QWidget):
    def __init__(self):
        super(WidgetWithBar, self).__init__()

        self.progress   = QProgressBar(self)
        self.progress   . setAlignment( Qt.AlignJustify )
        self.progress   . setValue(0)

        button1         = QPushButton( "Start Job", self )
        button1         . clicked.connect( self.handleStart )

        self.layout = QVBoxLayout()
        self.layout.addWidget( self.progress )
        self.layout.addWidget( button1 )
        self.setLayout( self.layout )

        self._worker = Worker(self)
        self._worker.progressChanged.connect(self.handleProgress)

    def handleProgress(self, step, count):
        if not self.progress.maximum():
            self.progress.setRange(0, count - 1)
        self.progress.setValue(step)

    def handleStart(self):
        if not self._worker.isRunning():
            self.progress.setRange(0,0)
            self._worker.start()

def main():
    app = QApplication(sys.argv)
    w = WidgetWithBar()
    w.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()