QMessageBox для блокировки родителя во время вычисления - PullRequest
1 голос
/ 08 февраля 2020

Я хочу использовать 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()

Что не так, как я могу сделать это правильно?

1 Ответ

2 голосов
/ 08 февраля 2020

Вы должны выполнить трудоемкую задачу в другом потоке и подать сигнал, что задача завершена. Чтобы закрыть 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"])
...