Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Simple example of the correct way to use (Py)Qt(5) and QThread
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from itertools import count, islice
class Threaded(QObject):
result=pyqtSignal(int)
def __init__(self, parent=None, **kwargs):
super().__init__(parent, **kwargs)
@pyqtSlot()
def start(self): print("Thread started")
@pyqtSlot(int)
def calculatePrime(self, n):
primes=(n for n in count(2) if all(n % d for d in range(2, n)))
self.result.emit(list(islice(primes, 0, n))[-1])
class GUI(QWidget):
requestPrime=pyqtSignal(int)
def __init__(self, parent=None, **kwargs):
super().__init__(parent, **kwargs)
self._thread=QThread()
self._threaded=Threaded(result=self.displayPrime)
self.requestPrime.connect(self._threaded.calculatePrime)
self._thread.started.connect(self._threaded.start)
self._threaded.moveToThread(self._thread)
qApp.aboutToQuit.connect(self._thread.quit)
self._thread.start()
l=QVBoxLayout(self)
self._iterationLE=QLineEdit(self, placeholderText="Iteration (n)")
l.addWidget(self._iterationLE)
self._requestBtn=QPushButton(
"Calculate Prime", self, clicked=self.primeRequested)
l.addWidget(self._requestBtn)
self._busy=QProgressBar(self)
l.addWidget(self._busy)
self._resultLbl=QLabel("Result:", self)
l.addWidget(self._resultLbl)
@pyqtSlot()
def primeRequested(self):
try: n=int(self._iterationLE.text())
except: return
self.requestPrime.emit(n)
self._busy.setRange(0,0)
self._iterationLE.setEnabled(False)
self._requestBtn.setEnabled(False)
@pyqtSlot(int)
def displayPrime(self, prime):
self._resultLbl.setText("Result: {}".format(prime))
self._busy.setRange(0,100)
self._iterationLE.setEnabled(True)
self._requestBtn.setEnabled(True)
if __name__=="__main__":
from sys import exit, argv
a=QApplication(argv)
g=GUI()
g.show()
exit(a.exec_())
@bjones1

This comment has been minimized.

Copy link

bjones1 commented Feb 15, 2016

Rob, a quick question. I saw your helpful post of PyQt and read through your code. I'm unfamiliar with the use of result=self.displayPrime on line 26. I assume this is the equivalent of self.result.connect(GUI.displayPrime), but wondered if you had a hyperlink so I could read more about this (nice) syntax?

Thanks!

@jazzycamel

This comment has been minimized.

Copy link
Owner Author

jazzycamel commented Apr 12, 2016

Its the equivalent of self._threaded.result.connect(self.displayPrime), i.e. you pass a reference to the instance of GUI.displayPrime.

I don't have a hyperlink anywhere, but you can basically pass the name of any objects signal to its constructor as a keyword argument with a reference to an instance of the target object's slot.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.