2016-11-12 23 views
1

假設我有收集文件和稍後複製的任務。收集QProgressBar時顯示出一些不確定的「繁忙」狀態。在這個過程之後,我們將複製收集的文件並顯示進度。 問題是,我可以做任何事情,但不能連續進行。向下是PySide中的小代碼,它通過按下QButton 1和2來顯示這個工作,但不是在連續任務中。請幫忙。如何實現QProgressBar從「繁忙」模式到標準進度模式的轉換?

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

所以,如果我註釋掉上兩條線,要使用只需按下一個按鈕,進度條就不會顯示「忙」模式在所有啓動這兩個功能!

回答

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