I am trying to create and run a new thread each time I want to pop a message box from main thread. Wondering if this code below will cause memory leak or even a good practi
No it's not good practice. You should only do GUI stuff, including showing message boxes, from the main thread. Use signals and slots to communicate with the main thread, which can show the message box and provide a response for your secondary thread.
Here's a simple example where a worker thread signals the main thread to show a message box, then checks the responses
dictionary for the message box response (basic dictionary operations are thread safe). This example should also work for multiple threads as the responses are keyed under the thread name.
from PyQt4 import QtCore, QtGui
import threading, time, sys
class Worker(QtCore.QObject):
def __init__(self, app):
super(Worker, self).__init__()
self.app = app
def do_stuff(self):
thread_name = threading.current_thread().name
self.app.responses[thread_name] = None
self.app.showMessageBox.emit(thread_name,
'information',
'Hello',
'Thread {} sent this message.'.format(thread_name))
while self.app.responses[thread_name] is None:
time.sleep(0.1)
print 'Thread {} got response from message box: {}'.format(thread_name, self.app.responses[thread_name])
class MainWindow(QtGui.QMainWindow):
showMessageBox = QtCore.pyqtSignal(str, str, str, str)
def __init__(self, sys_argv):
super(MainWindow, self).__init__(sys_argv)
self.responses = {}
self.showMessageBox.connect(self.on_show_message_box)
self.worker = Worker(self)
self.thread = QtCore.QThread()
self.worker.moveToThread(self.thread)
self.thread.started.connect(self.worker.do_stuff)
self.thread.start()
def on_show_message_box(self, id, severity, title, text):
self.responses[str(id)] = getattr(QtGui.QMessageBox, str(severity))(self, title, text)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
win = MainWindow(None)
win.show()
sys.exit(app.exec_())