Как показать модальный QDialog без взаимодействия с пользователем? - PullRequest
2 голосов
/ 20 июня 2019

Я хотел бы показать безрамочный модальный диалог, который не обеспечивает никакого взаимодействия, даже не возможность закрыть диалог. Идея состоит в том, чтобы открыть диалоговое окно для отображения сообщения с предупреждением о продолжающейся операции, запустить эту операцию, а затем закрыть диалоговое окно.

Qt doc, похоже, указывает на то, что можно отобразить модальное диалоговое окно без выполнения его цикла событий: https://doc.qt.io/qt-5/qdialog.html#modal-dialogs

Но когда я делаю это, диалог никогда не отображается должным образом на экране. Я получаю черный виджет, и его ярлыки остаются невидимыми.

Это моя попытка:

from PyQt5.QtGui import *
from PyQt5.QtWidgets import *


class ModalInfoDialog(QDialog):
    """
    Frameless modal dialog with no interaction
    """

    def __init__(self, text1="Loading project",
                 text2="", parent=None):
        super().__init__(parent)
        self.setWindowFlags(Qt.Window | Qt.FramelessWindowHint)
        self.setModal(True)
        self.setStyleSheet(
            """
            QDialog {
                background-color: white;
                border: none;
            }
            """)

        layout = QVBoxLayout(self)
        self.setLayout(layout)

        firstLine = QLabel(text1)
        secondLine = QLabel(text2)

        layout.addWidget(firstLine)
        layout.addWidget(secondLine)


import time
app = QApplication([])

d = ModalInfoDialog("haha!", "huh?")
d.show()
QApplication.processEvents()  # does not help
time.sleep(3)
d.close()

1 Ответ

3 голосов
/ 20 июня 2019

Вам не нужно использовать processEvents, вместо этого вы реализуете задачу в другом потоке, в этом случае я создал QObject, который живет в другом потоке и выдает сигнал, когда задача заканчивается, что служит для закрытия окна.

import time
from PyQt5 import QtCore, QtWidgets


class ModalInfoDialog(QtWidgets.QDialog):
    """
    Frameless modal dialog with no interaction
    """

    def __init__(self, text1="Loading project", text2="", parent=None):
        super().__init__(parent)
        self.setWindowFlags(QtCore.Qt.Window | QtCore.Qt.FramelessWindowHint)
        self.setModal(True)
        self.setStyleSheet(
            """
            QDialog {
                background-color: white;
                border: none;
            }
            """
        )

        layout = QtWidgets.QVBoxLayout(self)

        firstLine = QtWidgets.QLabel(text1)
        secondLine = QtWidgets.QLabel(text2)

        layout.addWidget(firstLine)
        layout.addWidget(secondLine)


class Worker(QtCore.QObject):
    finished = QtCore.pyqtSignal()

    @QtCore.pyqtSlot()
    def task(self):
        time.sleep(3)
        self.finished.emit()


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    d = ModalInfoDialog("haha!", "huh?")
    d.show()
    thread = QtCore.QThread(d)
    worker = Worker()
    worker.finished.connect(d.close)
    worker.moveToThread(thread)
    thread.started.connect(worker.task)
    thread.start()
    sys.exit(app.exec_())
...