每次我想从主线程中弹出一个消息框时,我都试图创建并运行一个新线程。想知道下面这段代码是否会导致内存泄漏甚至是一个好的做法。如果可以改进,怎么办?
class UIThread (threading.Thread):
def __init__(self, message):
print "UIThread init(). msg = " + message
this_thread = threading.Thread.__init__(self)
this_thread.daemon = True
self.message = message
self.qtapp = QApplication(sys.argv)
self.w = QWidget()
def run(self):
print "UIThread running"
result = QMessageBox.warning(self.w, 'WARNING', self.message, QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
if result == QMessageBox.Yes:
print 'Yes.'
else:
print 'No.'
sys.exit(self.qtapp.exec_())
...
messagebox = UIThread("Test")
messagebox.start()
....
messagebox = UIThread("Test 2")
messagebox.start()
....
# will pop up more message boxes throughout the program
答案 0 :(得分:1)
不,这不是好习惯。你应该只从主线程做GUI内容,包括显示消息框。使用信号和插槽与主线程进行通信,主线程可以显示消息框并为您的辅助线程提供响应。
这是一个简单的例子,其中一个工作线程通知主线程显示一个消息框,然后检查responses
字典中的消息框响应(基本字典操作是线程安全的)。此示例也适用于多个线程,因为响应在线程名称下键入。
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_())