使用子线程向主线程的槽函数发送信号方式,由主线程实例化QMessageBox类来弹窗。如果由子线程实例化QMessageBox类会卡退。
原因不明,如有错误望斧正,谢谢!
使用QThread:
import sys
import threading
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
class WorkerThread(QThread):
finished = pyqtSignal(str, str)
def __init__(self,dialogObject):
self.dialogObject=dialogObject
super(WorkerThread, self).__init__()
def run(self):
self.finished.connect(self.dialogObject.ShowDialog)
self.finished.emit('Information', 'message')
class DialogClass(QObject):
def ShowDialog(self,type, message):
self.message=message
if type == 'Information':
self.InformationDialog()
elif type == 'Error':
self.ErrorDialog()
elif type == 'Warning':
self.WarningDialog()
else:
self.NormalDialog()
self.dialog.setText(self.message)
self.dialog.exec_()
def NormalDialog(self):
self.dialog = QMessageBox()
def InformationDialog(self):
self.dialog = QMessageBox(QMessageBox.Information, 'Information', self.message, QMessageBox.Ok)
def ErrorDialog(self):
self.dialog = QMessageBox(QMessageBox.Critical, 'Error', self.message, QMessageBox.Ok)
def WarningDialog(self):
self.dialog = QMessageBox(QMessageBox.Critical, 'Warning', self.message, QMessageBox.Ok)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.dialogObject = DialogClass()
self.setWindowTitle('Main Window')
self.setGeometry(100, 100, 300, 200)
self.button = QPushButton('Start Work', self)
self.button.setGeometry(50, 50, 200, 100)
self.button.clicked.connect(self.start_work)
def start_work(self):
workerThread = WorkerThread(self.dialogObject)
workerThread.start()
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
使用thread.Thread:
import sys
import threading
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
class WorkerThread(threading.Thread):
def __init__(self,dialogObject):
self.dialogObject=dialogObject
super(WorkerThread, self).__init__()
def run(self):
worker = Worker()
worker.finished.connect(self.dialogObject.ShowDialog)
worker.DoWork()
class Worker(QObject):
finished = pyqtSignal(str, str)
def DoWork(self):
self.finished.emit('Information','message')
class DialogClass(QObject):
def ShowDialog(self,type, message):
self.message=message
if type == 'Information':
self.InformationDialog()
elif type == 'Error':
self.ErrorDialog()
elif type == 'Warning':
self.WarningDialog()
else:
self.NormalDialog()
self.dialog.setText(self.message)
self.dialog.exec_()
def NormalDialog(self):
self.dialog = QMessageBox()
def InformationDialog(self):
self.dialog = QMessageBox(QMessageBox.Information, 'Information', self.message, QMessageBox.Ok)
def ErrorDialog(self):
self.dialog = QMessageBox(QMessageBox.Critical, 'Error', self.message, QMessageBox.Ok)
def WarningDialog(self):
self.dialog = QMessageBox(QMessageBox.Critical, 'Warning', self.message, QMessageBox.Ok)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.dialogObject = DialogClass()
self.setWindowTitle('Main Window')
self.setGeometry(100, 100, 300, 200)
self.button = QPushButton('Start Work', self)
self.button.setGeometry(50, 50, 200, 100)
self.button.clicked.connect(self.start_work)
def start_work(self):
workerThread = WorkerThread(self.dialogObject)
workerThread.start()
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
在使用thread.Thread版本中,如果按下面的写法会报错:TypeError: WorkerThread cannot be converted to PyQt5.QtCore.QObject in this context。所以定义一个Worker类继承自QObject,把运行的逻辑放在Worker类里。
class WorkerThread(threading.Thread):
finished = pyqtSignal(str, str)
def __init__(self,dialogObject):
self.dialogObject=dialogObject
super(WorkerThread, self).__init__()
def run(self):
self.finished.connect(self.dialogObject.ShowDialog)
self.finished.emit('Information', 'message')