Reputation: 3257
Let's say I have task of collecting files and later on copying. While collecting the QProgressBar is showing some indefinite, "busy" status. After that process is moving on to copy collected files and show progress. The problem is that I can do any of it but not together in continuous process. Down is little code in PySide that shows this working by pressing QButton 1 and 2, but not in continuous task. Please help.
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()
So if I would comment out upper two lines, To start both functions with pressing just first button, progress bar wouldn't show "busy" mode at all!
Upvotes: 1
Views: 75
Reputation: 120608
You should do the time-consuming work in a separate thread, and emit signals to update the progress. Below is a simple demo based on your example:
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()
Upvotes: 2