user2638731
user2638731

Reputation: 605

PyQt: Wait until widget closes

I have a window/widget that shows after I press a button, is there a way to make the main window wait until the widget closes out? I am using .show() right now and I have tried using .exec_() already but it gives me this error:

AttributeError: 'MainWindow' object has no attribute 'exec_'

Any help?

Upvotes: 1

Views: 8230

Answers (2)

Veysel Olgun
Veysel Olgun

Reputation: 598

I am not good at PyQt5, but you can also use QDialog to block main window until second window closed, simple code is below

from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QLabel, QVBoxLayout, QDialog
import sys

class AnotherWindow(QDialog):
    def __init__(self):
        super().__init__()
        layout = QVBoxLayout()
        self.label = QLabel("Another Window")
        layout.addWidget(self.label)
        self.setLayout(layout)


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.w = None  # No external window yet.
        self.button = QPushButton("Push for Window")
        self.button.clicked.connect(self.show_new_window)
        self.setCentralWidget(self.button)

    def show_new_window(self, checked):
        if self.w is None:
            self.w = AnotherWindow()
        self.w.exec()
        print("Another window closed")

if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = MainWindow()
    w.show()
    app.exec()

Upvotes: 0

ekhumoro
ekhumoro

Reputation: 120768

Use a local event-loop to wait until the window/widget closes:

widget = QWidget()
widget.setAttribute(Qt.WA_DeleteOnClose)
widget.show()
loop = QEventLoop()
widget.destroyed.connect(loop.quit)
loop.exec() # wait ...
print('finished')

To also block interaction with other windows, set the window modality:

widget.setWindowModality(Qt.ApplicationModal)

or for top-level windows with a parent:

window.setWindowModality(Qt.WindowModal)

Of course, if you can change the window/widget to a QDialog, then none of the above is necessary, since the same functionality is provided by exec:

widget = QDialog()
widget.exec() # wait ...

Upvotes: 6

Related Questions