在子窗口存活时阻塞QMainWindow,pyqt

4 投票
6 回答
15595 浏览
提问于 2025-04-17 22:20

我想要的是,当用户按下按钮时,主窗口会被阻塞,这样用户就必须填写表单后才能继续操作。

6 个回答

0

好的,你想要在子窗口关闭之前,阻止父窗口的操作。

dialog = QInputDialog()
dialog.exec_()

可以使用exec_()这个函数,它会一直等到子窗口关闭后才继续执行。

想了解更多信息,可以查看:

从主PyQt窗口启动一个PyQt窗口,并获取用户输入?

Python - 让一个窗口在另一个窗口上方显示,直到点击按钮才能访问其他窗口

0

你可以创建一个自己的对话框(QDialog)或者窗口(QWidget),然后在主窗口的构造函数里把它连接起来。你需要把这段代码从C++转换成Python:

QObject::connect(myPushButton, SIGNAL(clicked), this, SLOT(on_myPushButton()));

//...

void MainWindow::on_myPushButton()
{
    Dialog d;
    int retVal = d.exec();// this is a blocking call
    // Here the user has finished filling out the form.
    // save any data that should be in the form, or respond to the retVal

}

编辑:我添加了一个关于如何使用 QDialog::exec() 的文档链接。

http://qt-project.org/doc/qt-5/qdialog.html#exec

希望这对你有帮助。

2

这就是你需要的

self.setWindowModality(QtCore.Qt.ApplicationModal)
14

你不需要按照其他回答的建议去做。使用任何 exec() 方法肯定会导致错误,因为你的界面代码可能会被重新进入。别这么做。

你只需要在显示窗口之前设置正确的窗口模式(这点非常重要)。所以:

widget.setWindowModality(Qt.ApplicationModal)
widget.show()

如果你希望这个窗口只阻止某个特定的窗口,而不是整个应用程序:

widget.setWindowFlags(widget.windowFlags() | Qt.Window)
widget.setParent(otherWindow)
widget.setWindowModality(Qt.WindowModal)
widget.show()

请注意,这段代码仅适用于 PyQt4,Qt 5 不适用,因为在 Qt 5 中,窗口的功能属于一个与 QWidget 分开的类。

10

你可以使用一个叫做 QDialog 的对话框,并通过 exec 方法来显示它。这样做会让应用程序暂停,直到这个对话框被关闭为止。调用 exec 方法后返回的值可以告诉你这个对话框是被关闭了还是被取消了,也就是说,用户是否在没有保存更改的情况下关闭了它。

下面是一个简单的示例脚本,展示了如何使用 QDialog

from PyQt5 import QtWidgets, QtCore
# from PyQt6 import QtWidgets, QtCore

class Dialog(QtWidgets.QDialog):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.checkbox1 = QtWidgets.QCheckBox('Option one')
        self.checkbox2 = QtWidgets.QCheckBox('Option two')
        self.buttonOk = QtWidgets.QPushButton('Ok')
        self.buttonOk.clicked.connect(self.accept)
        self.buttonCancel = QtWidgets.QPushButton('Cancel')
        self.buttonCancel.clicked.connect(self.reject)
        layout = QtWidgets.QGridLayout(self)
        layout.addWidget(self.checkbox1, 0, 0, 1, 2)
        layout.addWidget(self.checkbox2, 1, 0, 1, 2)
        layout.addWidget(self.buttonOk, 2, 0)
        layout.addWidget(self.buttonCancel, 2, 1)

class Window(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        widget = QtWidgets.QWidget()
        layout = QtWidgets.QVBoxLayout(widget)
        self.button = QtWidgets.QPushButton('Show Dialog')
        self.button.clicked.connect(self.handleButton)
        layout.addWidget(self.button)
        self.setCentralWidget(widget)

    def handleButton(self):
        dialog = Dialog(self)
        if dialog.exec_() == QtWidgets.QDialog.DialogCode.Accepted:
            print('Option one:', dialog.checkbox1.isChecked())
            print('Option two:', dialog.checkbox2.isChecked())
        else:
            print('Cancelled')
        dialog.deleteLater()

if __name__ == '__main__':

    app = QtWidgets.QApplication(['Test'])
    window = Window()
    window.setGeometry(500, 300, 200, 100)
    window.show()
    app.exec()

撰写回答