如何在 QProgressBar 中实现从 "busy" 类模式到标准进度模式的转换?

How to achieve transition in QProgressBar from "busy" like mode into standard progress mode?

假设我有收集文件和稍后复制的任务。收集 QProgressBar 时显示一些不确定的 "busy" 状态。在该过程继续复制收集的文件并显示进度之后。 问题是我可以做任何一个,但不能在连续的过程中一起做。 PySide 中的 Down 代码很少,它通过按 QButton 1 和 2 来显示此功能,但不是在连续任务中。请帮忙

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

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( "Waiting for Job", self )
        button1         . clicked.connect( self.wait )
        button2         = QPushButton( "Doing Job", self )
        button2         . clicked.connect( self.go )

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

    def wait(self):
        self.progress.setRange(0,0)
        # -- this two lines to comment out 
        #time.sleep( 2 )
        #self.go()
        # -- EOLines to comment out

    def go(self):
        n = 20
        self.progress.setRange(0,n)
        # DO SOMETHING TO SHOW THE PROGRESS
        for t in range(n):
            time.sleep(.1)
            self.progress.setValue(t+1)

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

if __name__ == '__main__':
    main()

因此,如果我要注释掉上面两行,只需按第一个按钮即可启动这两个功能,进度条根本不会显示 "busy" 模式!

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

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()