如何创建一个独立的 non-modal 对话框
How to create an independent non-modal dialog
我正在尝试扩展此解决方案 Non modal dialog
from PyQt5 import QtWidgets
dialog = None
class Dialog(QtWidgets.QDialog):
def __init__(self, *args, **kwargs):
super(Dialog, self).__init__(*args, **kwargs)
self.setWindowTitle('A floating dialog')
self.resize(250,250)
class Window(QtWidgets.QWidget):
def __init__(self):
QtWidgets.QWidget.__init__(self)
button = QtWidgets.QPushButton('Open Dialog', self)
button.clicked.connect(self.handleOpenDialog)
self.resize(300, 200)
self._dialog = None
global dialog
dialog = Dialog(self)
dialog.show()
def handleOpenDialog(self):
if self._dialog is None:
self._dialog = QtWidgets.QDialog(self)
self._dialog.resize(200, 100)
self._dialog.exec_()
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
win = Window()
win.show()
sys.exit(app.exec_())
如果标题不相关,我们深表歉意。我想要一个 dialog/window 独立于所有现有的 window/dialogs,并且可以始终与之交互,即应用程序 window/any 对话框的 GUI 循环不会阻止此 non-model对话。为简单起见,我在上面的代码片段中使用了全局变量 dialog
,它将保存 non-modal 对话框实例。
当上面的程序是运行时,主window出现along-with和non-modal对话框,这两个对话框都是用户交互的,但是当按钮被点击时, self._dialog
的 GUI 循环开始,用户无法再与浮动对话框和应用程序 window 交互。我想要的是能够与 dialog
交互,但不能与 Window
交互
我想要类似于以下示例的行为:
我从主 window 打开了帮助对话框,然后我打开了一个 non-modal 对话框,该对话框出现在主 window 的顶部,并且无法与主 [=40] 交互=],但仍然不会阻止帮助 dialog/window 并允许用户与此 non-modal window 交互,即示例中的帮助对话框。
当使用 exec()
打开对话框时,它将默认为 application-modal. This means it will block all other windows in the application, regardless of whether they're parented to other windows or not. To make a dialog modal for only one window, it must be parented to that window and also have its modality explicitly set to window-modal。
对于相对于所有其他 windows(及其任何模态对话框)而言完全非模态的对话框,它必须没有父级,然后使用 show()
打开。但是,这样做的一个副作用是它不会在 main-window 关闭时自动关闭。要解决此问题,可以在 main-window.
的 closeEvent()
中明确关闭它
这是一个实现上述所有内容的简单演示:
import sys
from PyQt5 import QtCore, QtWidgets
class Window(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('Main Window')
self.setGeometry(400, 100, 300, 200)
self._help_dialog = None
self._other_dialog = None
self.buttonHelp = QtWidgets.QPushButton('Open Help')
self.buttonHelp.clicked.connect(self.handleOpenHelp)
self.buttonDialog = QtWidgets.QPushButton('Open Dialog')
self.buttonDialog.clicked.connect(self.handleOpenDialog)
layout = QtWidgets.QHBoxLayout(self)
layout.addWidget(self.buttonDialog)
layout.addWidget(self.buttonHelp)
self.handleOpenHelp()
def handleOpenDialog(self):
if self._other_dialog is None:
self._other_dialog = QtWidgets.QDialog(self)
self._other_dialog.setWindowModality(QtCore.Qt.WindowModal)
self._other_dialog.setWindowTitle('Other Dialog')
self._other_dialog.resize(200, 100)
self._other_dialog.exec_()
def handleOpenHelp(self):
if self._help_dialog is None:
self._help_dialog = QtWidgets.QDialog()
self._help_dialog.setWindowTitle('Help Dialog')
self._help_dialog.setGeometry(750, 100, 250, 250)
self._help_dialog.show()
def closeEvent(self, event):
if self._help_dialog is not None:
self._help_dialog.close()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())
我正在尝试扩展此解决方案 Non modal dialog
from PyQt5 import QtWidgets
dialog = None
class Dialog(QtWidgets.QDialog):
def __init__(self, *args, **kwargs):
super(Dialog, self).__init__(*args, **kwargs)
self.setWindowTitle('A floating dialog')
self.resize(250,250)
class Window(QtWidgets.QWidget):
def __init__(self):
QtWidgets.QWidget.__init__(self)
button = QtWidgets.QPushButton('Open Dialog', self)
button.clicked.connect(self.handleOpenDialog)
self.resize(300, 200)
self._dialog = None
global dialog
dialog = Dialog(self)
dialog.show()
def handleOpenDialog(self):
if self._dialog is None:
self._dialog = QtWidgets.QDialog(self)
self._dialog.resize(200, 100)
self._dialog.exec_()
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
win = Window()
win.show()
sys.exit(app.exec_())
如果标题不相关,我们深表歉意。我想要一个 dialog/window 独立于所有现有的 window/dialogs,并且可以始终与之交互,即应用程序 window/any 对话框的 GUI 循环不会阻止此 non-model对话。为简单起见,我在上面的代码片段中使用了全局变量 dialog
,它将保存 non-modal 对话框实例。
当上面的程序是运行时,主window出现along-with和non-modal对话框,这两个对话框都是用户交互的,但是当按钮被点击时, self._dialog
的 GUI 循环开始,用户无法再与浮动对话框和应用程序 window 交互。我想要的是能够与 dialog
交互,但不能与 Window
我想要类似于以下示例的行为:
我从主 window 打开了帮助对话框,然后我打开了一个 non-modal 对话框,该对话框出现在主 window 的顶部,并且无法与主 [=40] 交互=],但仍然不会阻止帮助 dialog/window 并允许用户与此 non-modal window 交互,即示例中的帮助对话框。
当使用 exec()
打开对话框时,它将默认为 application-modal. This means it will block all other windows in the application, regardless of whether they're parented to other windows or not. To make a dialog modal for only one window, it must be parented to that window and also have its modality explicitly set to window-modal。
对于相对于所有其他 windows(及其任何模态对话框)而言完全非模态的对话框,它必须没有父级,然后使用 show()
打开。但是,这样做的一个副作用是它不会在 main-window 关闭时自动关闭。要解决此问题,可以在 main-window.
closeEvent()
中明确关闭它
这是一个实现上述所有内容的简单演示:
import sys
from PyQt5 import QtCore, QtWidgets
class Window(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('Main Window')
self.setGeometry(400, 100, 300, 200)
self._help_dialog = None
self._other_dialog = None
self.buttonHelp = QtWidgets.QPushButton('Open Help')
self.buttonHelp.clicked.connect(self.handleOpenHelp)
self.buttonDialog = QtWidgets.QPushButton('Open Dialog')
self.buttonDialog.clicked.connect(self.handleOpenDialog)
layout = QtWidgets.QHBoxLayout(self)
layout.addWidget(self.buttonDialog)
layout.addWidget(self.buttonHelp)
self.handleOpenHelp()
def handleOpenDialog(self):
if self._other_dialog is None:
self._other_dialog = QtWidgets.QDialog(self)
self._other_dialog.setWindowModality(QtCore.Qt.WindowModal)
self._other_dialog.setWindowTitle('Other Dialog')
self._other_dialog.resize(200, 100)
self._other_dialog.exec_()
def handleOpenHelp(self):
if self._help_dialog is None:
self._help_dialog = QtWidgets.QDialog()
self._help_dialog.setWindowTitle('Help Dialog')
self._help_dialog.setGeometry(750, 100, 250, 250)
self._help_dialog.show()
def closeEvent(self, event):
if self._help_dialog is not None:
self._help_dialog.close()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())