QMessageBox 在计算时阻止父级
QMessageBox to block parent while calculation
我想在计算时使用 QMessageBox
来阻止其父级 QDialog
。我遇到了类似的事情,但这不起作用。
msgBox = QtWidgets.QMessageBox()
msgBox.setWindowTitle('Working ....')
msgBox.setText("Working, please wait ...")
msgBox.setStandardButtons(QtWidgets.QMessageBox.NoButton)
msgBox.exec_()
(doing some time consuming work)
msgBox.close()
有什么问题,我该如何正确处理?
您必须在另一个线程中执行耗时的任务,并通过信号通知任务执行完毕。要关闭 QMessageBox,您必须使用 accept() 方法:
import threading
from PyQt5 import QtCore, QtWidgets
class Worker(QtCore.QObject):
started = QtCore.pyqtSignal()
finished = QtCore.pyqtSignal()
def execute(self, func, args):
threading.Thread(target=self._execute, args=(func, args,), daemon=True).start()
def _execute(self, func, args):
self.started.emit()
func(*args)
self.finished.emit()
def consuming_work(arg1, arg2):
import time
print(arg1, arg2)
time.sleep(5)
print("finish")
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
msgBox = QtWidgets.QMessageBox()
msgBox.setWindowTitle("Working ....")
msgBox.setText("Working, please wait ...")
msgBox.setStandardButtons(QtWidgets.QMessageBox.NoButton)
worker = Worker(msgBox)
worker.finished.connect(msgBox.accept)
worker.execute(consuming_work, ["Stack", "Overflow"])
msgBox.exec_()
更新:
import threading
from PyQt5 import QtCore, QtWidgets
class WorkerMessageBox(QtWidgets.QMessageBox):
started = QtCore.pyqtSignal()
finished = QtCore.pyqtSignal()
def __init__(self, parent=None):
super().__init__(parent)
self.finished.connect(self.accept)
def execute(self, func, args):
threading.Thread(target=self._execute, args=(func, args,), daemon=True).start()
return self.exec_()
def _execute(self, func, args):
self.started.emit()
func(*args)
self.finished.emit()
def consuming_work(arg1, arg2):
import time
print(arg1, arg2)
time.sleep(5)
print("finish")
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
msgBox = WorkerMessageBox()
msgBox.setWindowTitle("Working ....")
msgBox.setText("Working, please wait ...")
msgBox.setStandardButtons(QtWidgets.QMessageBox.NoButton)
msgBox.execute(consuming_work, ["Stack", "Overflow"])
我想在计算时使用 QMessageBox
来阻止其父级 QDialog
。我遇到了类似的事情,但这不起作用。
msgBox = QtWidgets.QMessageBox()
msgBox.setWindowTitle('Working ....')
msgBox.setText("Working, please wait ...")
msgBox.setStandardButtons(QtWidgets.QMessageBox.NoButton)
msgBox.exec_()
(doing some time consuming work)
msgBox.close()
有什么问题,我该如何正确处理?
您必须在另一个线程中执行耗时的任务,并通过信号通知任务执行完毕。要关闭 QMessageBox,您必须使用 accept() 方法:
import threading
from PyQt5 import QtCore, QtWidgets
class Worker(QtCore.QObject):
started = QtCore.pyqtSignal()
finished = QtCore.pyqtSignal()
def execute(self, func, args):
threading.Thread(target=self._execute, args=(func, args,), daemon=True).start()
def _execute(self, func, args):
self.started.emit()
func(*args)
self.finished.emit()
def consuming_work(arg1, arg2):
import time
print(arg1, arg2)
time.sleep(5)
print("finish")
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
msgBox = QtWidgets.QMessageBox()
msgBox.setWindowTitle("Working ....")
msgBox.setText("Working, please wait ...")
msgBox.setStandardButtons(QtWidgets.QMessageBox.NoButton)
worker = Worker(msgBox)
worker.finished.connect(msgBox.accept)
worker.execute(consuming_work, ["Stack", "Overflow"])
msgBox.exec_()
更新:
import threading
from PyQt5 import QtCore, QtWidgets
class WorkerMessageBox(QtWidgets.QMessageBox):
started = QtCore.pyqtSignal()
finished = QtCore.pyqtSignal()
def __init__(self, parent=None):
super().__init__(parent)
self.finished.connect(self.accept)
def execute(self, func, args):
threading.Thread(target=self._execute, args=(func, args,), daemon=True).start()
return self.exec_()
def _execute(self, func, args):
self.started.emit()
func(*args)
self.finished.emit()
def consuming_work(arg1, arg2):
import time
print(arg1, arg2)
time.sleep(5)
print("finish")
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
msgBox = WorkerMessageBox()
msgBox.setWindowTitle("Working ....")
msgBox.setText("Working, please wait ...")
msgBox.setStandardButtons(QtWidgets.QMessageBox.NoButton)
msgBox.execute(consuming_work, ["Stack", "Overflow"])