QMessageBox在计算时阻止父级

问题描述 投票:1回答:1

我想在计算时使用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()

怎么了,我该怎么做?

python pyqt pyqt5 qmessagebox
1个回答
2
投票

您必须在另一个线程中执行耗时的任务,并通过信号通知任务已完成执行。要关闭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"])
© www.soinside.com 2019 - 2024. All rights reserved.