I have tried doing it with multiprocessing module to no avail. I get the following error:
TypeError: cannot pickle ‘MainWindow’ object
import time, multiprocessing from PyQt5 import QtWidgets, QtGui class MainWindow(QtWidgets.QWidget): def __init__(self): super().__init__() self.initializeUI() self.show() def initializeUI(self): # UI stuff self.setLayout(QtWidgets.QGridLayout()) dummy_btn = QtWidgets.QPushButton("Ok") self.layout().addWidget(dummy_btn) updater = multiprocessing.Process(target=self.update_function, args=[]) updater.start() def update_function(self): time.sleep(2) print("This text, again!") self.update_function() app = QtWidgets.QApplication([]) mw = MainWindow() app.exec_()
Advertisement
Answer
the proper way to do this is to not use any sort of parallel mechanism, instead use QTimer.singleshot
, as QT doesn’t work well with multiprocessing or threading, and if you want to repeat it then you can just connect the function to a Qtimer.timeout
signal and set the timer on repeat using Qtimer.start()
as in this tutorial
import time, multiprocessing from PyQt5 import QtWidgets, QtGui from PyQt5.QtCore import QTimer class MainWindow(QtWidgets.QWidget): def __init__(self): super().__init__() self.initializeUI() self.show() def initializeUI(self): # UI stuff self.setLayout(QtWidgets.QGridLayout()) dummy_btn = QtWidgets.QPushButton("Ok") self.layout().addWidget(dummy_btn) self.timer = QTimer(self) # self.timer.singleShot(2000,self.update_function) # for one time call only self.timer.timeout.connect(self.update_function) self.timer.start(2000) # time in milliseconds. def update_function(self): # time.sleep(2) this is not needed print("This text, again!") self.update() # this had a typo app = QtWidgets.QApplication([]) mw = MainWindow() app.exec_()
Edit: to clarify on working with threads and multiprocessing, if you use multiprocessing for example there are many precautions, such as putting an if __name__ == "__main__":
guard on your code, and not use anything that belong to QT inside the subprocesses, and just use it for running things that don’t need QT, like reading files and doing calculations.
as for threading, using any QWidget object in another thread other than your main application thread is going to crash your application, you can emit signals from child threads for signaling, but you cannot update the GUI on another thread, so only use QT objects that don’t touch the GUI inside threads. (like networking, reading files, and sharing the CPU for extra calculations)