Bloquea QMainWindow mientras el widget hijo está vivo, pyqt

Quiero que cuando el usuario presione el botón aparezca un formulario después de que se haya bloqueado MainWindow hasta que se llene el formulario

Debe usar un QDialog y mostrarlo usando exec , que bloqueará el rest de la aplicación hasta que se cierre. El valor de retorno de exec también le informa si el formulario se cerró sin confirmar los cambios (es decir, se canceló).

Aquí hay un sencillo script de demostración que muestra cómo usar un 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_()) 

No necesitas hacer nada que sugieran las otras respuestas. El uso de cualquier método exec() es una forma segura de tener errores, ya que de repente su código GUI puede volver a ingresar. No lo hagas

Todo lo que necesita hacer es establecer la modalidad de ventana adecuada antes de mostrarla (esa es la parte importante). Asi que:

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

Si desea que la ventana bloquee solo alguna otra ventana, no la aplicación completa:

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

Tenga en cuenta que este código es solo para PyQt4, no funcionará con Qt 5, ya que la funcionalidad de la ventana pertenece a una clase separada de QWidget.

Bien, entonces quiere bloquear la ventana principal hasta que la ventana secundaria se haya cerrado.

 dialog = QInputDialog() dialog.exec_() 

Use la función exec_ (), se bloqueará hasta que la ventana secundaria no se cierre

Para más información:

iniciar una ventana de PyQT desde una ventana principal de PyQt y obtener la entrada del usuario?

Python: haga que una ventana aparezca encima de otra, bloquee el acceso a otras ventanas hasta que se haga clic en el botón

Subclasifique su QDialog o su QWidget con su formulario, y luego conéctelo así en la construcción de su ventana principal. Querrá convertir este código de c ++ a 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 } 

EDITAR: Se agregó un enlace a los documentos sobre el uso de QDialog::exec()

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

Espero que ayude.

debe crear widgets heredados de Qdialog

 AjoutArBase, AjoutArForm = uic.loadUiType('ajoutArticle.ui') class AjoutArticle(AjoutArBase,QtGui.QDialog): 

Esto es lo que necesitas

 self.setWindowModality(QtCore.Qt.ApplicationModal)