python - 如何在没有用户交互的情况下显示模态 QDialog?
问题描述
我想展示一个不提供任何交互的无框模态对话框,甚至不提供关闭对话框的能力。这个想法是打开对话框以显示一个长时间操作正在进行的消息警告,运行该操作,而不是关闭对话框。
qt 文档似乎表明可以在不执行其事件循环的情况下显示模式对话框: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()
解决方案
您不必使用 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_())
推荐阅读
- ldap - Artifactory ldaps 错误的 url/端口
- java - 在Java中通过索引查找第一对最大和
- java - Java 空 Optional 的类型是什么?
- opengl - C++ OpenGL, using more than one uniform
- c# - Visual Studio Extension 在调试时工作,但是当我安装 VSIX 时它不工作
- android - 无法为模拟器构建应用程序
- sql - 如何创建一个新表,基于具有动态内容的现有表,但将历史记录保留在新表中?
- excel - VBA Excel - 循环输出结果列组为 3
- c# - 如果打开了 CSV/Excel 文件,则使用 MessageBox 通知用户并终止应用程序的其余执行 [C# - WPF 应用程序]
- firebase - 用户注册firebase时如何保存名称?