Block QMainWindow while child widget is alive , py

2020-03-30 15:48发布

I want when the user press the button a form will appear after MainWindow is blocked pending form filling

标签: python qt pyqt4
6条回答
该账号已被封号
2楼-- · 2020-03-30 16:27

You need to use a QDialog and show it using exec, which will block the rest of the application until it is closed. The return value of exec also tells you whether the form was closed without committing changes (i.e. cancelled).

Here is a simple demo script that shows how to use a QDialog:

from PyQt4 import QtCore, QtGui

class Dialog(QtGui.QDialog):
    def __init__(self, parent=None):
        QtGui.QDialog.__init__(self, parent)
        self.checkbox1 = QtGui.QCheckBox('Option one', self)
        self.checkbox2 = QtGui.QCheckBox('Option two', self)
        self.buttonOk = QtGui.QPushButton('Ok', self)
        self.buttonOk.clicked.connect(self.accept)
        self.buttonCancel = QtGui.QPushButton('Cancel', self)
        self.buttonCancel.clicked.connect(self.reject)
        layout = QtGui.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(QtGui.QMainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        widget = QtGui.QWidget(self)
        layout = QtGui.QVBoxLayout(widget)
        self.button = QtGui.QPushButton('Show Dialog', self)
        self.button.clicked.connect(self.handleButton)
        layout.addWidget(self.button)
        self.setCentralWidget(widget)

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

if __name__ == '__main__':

    import sys
    app = QtGui.QApplication(sys.argv)
    window = Window()
    window.setGeometry(500, 300, 200, 100)
    window.show()
    sys.exit(app.exec_())
查看更多
一纸荒年 Trace。
3楼-- · 2020-03-30 16:29

Ok , so you want to block the parent window until the child window has been closed.

dialog = QInputDialog()
dialog.exec_()

Use the exec_() function , it will block until the child window is not closed

for further info :

launch a PyQT window from a main PyQt window, and get the user input?

Python - make a window appear on top of another, block access to other windows until button clicked

查看更多
狗以群分
4楼-- · 2020-03-30 16:32

Subclass your QDialog or your QWidget with your form, and then connect it like this in the constructory of your main window. You will want to convert this code from c++ to 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

}

EDIT: Added link to docs on using QDialog::exec()

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

Hope that helps.

查看更多
我命由我不由天
5楼-- · 2020-03-30 16:36

You don't need to do anything that the other answers suggest. Using any exec() methods is a surefire way to have bugs, since suddenly your gui code can be reentered. Don't do it.

All you need to do is to set proper window modality before you show it (that's the important part). So:

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

If you wish the window to block only some other window, not the entire application:

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

Note that this code is for PyQt4 only, it won't work with Qt 5 as there, the window functionality belongs in a class separate from QWidget.

查看更多
做个烂人
6楼-- · 2020-03-30 16:38

This is what you need

self.setWindowModality(QtCore.Qt.ApplicationModal)
查看更多
啃猪蹄的小仙女
7楼-- · 2020-03-30 16:39

must create Widget inherits from Qdialog

AjoutArBase, AjoutArForm = uic.loadUiType('ajoutArticle.ui')
class AjoutArticle(AjoutArBase,QtGui.QDialog):
查看更多
登录 后发表回答