Skip to content

Instantly share code, notes, and snippets.

@blakebjorn
Created December 12, 2016 00:13
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save blakebjorn/5b5bffe3e1e7867929d25b7be139b0be to your computer and use it in GitHub Desktop.
Save blakebjorn/5b5bffe3e1e7867929d25b7be139b0be to your computer and use it in GitHub Desktop.
PySide/PyQT non-blocking thread example
from PySide import QtCore, QtGui
import sys
import time
class MainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
#Build a UI
self.myLayout = QtGui.QVBoxLayout()
self.myCentralWidget = QtGui.QWidget()
self.myCentralWidget.setLayout(self.myLayout)
self.setCentralWidget(self.myCentralWidget)
self.progressBar = QtGui.QProgressBar()
self.progressBar.setRange(0, 100)
self.myLayout.addWidget(self.progressBar)
self.startButton = QtGui.QPushButton("Start!")
self.startButton.clicked.connect(self.start_thread)
self.myLayout.addWidget(self.startButton)
#Initialize the thread
self.myThread = MyQThread()
def start_thread(self):
if not self.myThread.isRunning():
self.myThread.maxRange = 1000
self.myThread.completionMessage = "this is a completion message"
self.myThread.completeSignal.connect(self.handle_thread_completion)
self.myThread.progressSignal.connect(self.handle_progress_bar)
self.myThread.start()
@QtCore.Slot(int)
def handle_progress_bar(self, e):
self.progressBar.setValue(e)
@QtCore.Slot(str)
def handle_thread_completion(self, e):
self.progressBar.setValue(0)
QtGui.QMessageBox.information(self, "Done", e)
class MyQThread(QtCore.QThread):
# Signals to relay thread progress to the main GUI thread
progressSignal = QtCore.Signal(int)
completeSignal = QtCore.Signal(str)
def __init__(self, parent=None):
super(MyQThread, self).__init__(parent)
# You can change variables defined here after initialization - but before calling start()
self.maxRange = 100
self.completionMessage = "done."
def run(self):
# blocking code goes here
emitStep = int(self.maxRange/100.0) # how many iterations correspond to 1% on the progress bar
for i in range(self.maxRange):
time.sleep(0.01)
if i%emitStep==0:
self.progressSignal.emit(i/emitStep)
self.completeSignal.emit(self.completionMessage)
if __name__=="__main__":
app = QtGui.QApplication(sys.argv)
win = MainWindow()
win.show()
sys.exit(app.exec_())
@waelali
Copy link

waelali commented May 4, 2018

Really? and what if you are calling a very long task that is calling hundreds of several small tasks or functions??
How will you do that ?

Imagine you have a controller that is calling a function (very long task) which it calls also too many functions of other classes in order to complete the task. How then you will do that into the run function? You can add that long Task function into the loop!!

All the examples are only talking about updating the progress bar counter and completion percentage.
There is so many cases that are more than that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment