I'm working with dialogs in PyQt6, and when I press either Accept or Cancel, the entire application closes. How can I prevent this?
When you create and display a dialog (for example, using QDialog.exec()), the dialog runs its own local event loop. Once you click OK or Cancel, the dialog closes and exec() returns a result. At that point, your code continues executing whatever comes after the dialog call.
If there's no main window being shown and no main event loop running, the application simply has nothing left to do — so it exits.
In other words, the dialog is your entire application. Once it's gone, everything shuts down.
The Fix: Run a Main Window with an Event Loop
To keep your application alive after the dialog closes, you need a main window that stays open and a properly running event loop. The dialog should be launched from that main window, so that when the dialog is dismissed, control returns to the main window which is still visible and active.
Here's a minimal complete example that demonstrates the correct setup:
import sys
from PyQt6.QtWidgets import (
QApplication, QDialog, QDialogButtonBox,
QMainWindow, QPushButton, QVBoxLayout,
)
class CustomDialog(QDialog):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("My Dialog")
buttons = QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel
self.button_box = QDialogButtonBox(buttons)
self.button_box.accepted.connect(self.accept)
self.button_box.rejected.connect(self.reject)
layout = QVBoxLayout()
layout.addWidget(self.button_box)
self.setLayout(layout)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Main Window")
button = QPushButton("Open Dialog")
button.clicked.connect(self.open_dialog)
self.setCentralWidget(button)
def open_dialog(self):
dialog = CustomDialog(self)
result = dialog.exec()
if result == QDialog.DialogCode.Accepted:
print("User clicked OK")
else:
print("User clicked Cancel")
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())
Let's walk through what's happening here.
The Main Window
The MainWindow class creates a simple window with a single button. When you click that button, it calls open_dialog(), which creates an instance of CustomDialog and displays it using exec().
Once you accept or cancel the dialog, exec() returns and you're back inside the open_dialog method. The main window is still visible and responsive — you can click the button again to reopen the dialog as many times as you like. If you're new to building windows in PyQt6, see our tutorial on creating your first window.
The Event Loop
The block at the bottom of the script is what keeps everything running:
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())
QApplication manages the main event loop for your application. Calling app.exec() starts that loop, which keeps the application alive, processing user input, repainting widgets, and handling signals and slots. The application will only exit when you close the main window (or explicitly call app.quit()).
Without this event loop, your script runs top-to-bottom and exits as soon as it reaches the end — which is exactly the behavior you'd see if a dialog was the only thing in your script.
Passing self as Parent
You might have noticed that we pass self when creating the dialog:
dialog = CustomDialog(self)
This sets the main window as the dialog's parent. It means the dialog will appear centered over the main window and will be properly tied to it in terms of window management. It's a good habit to set a parent for your dialogs whenever you can.
Summary
If your app is closing when you dismiss a dialog, make sure you have:
- A
QApplicationinstance with its event loop running viaapp.exec(). - A main window that is shown using
.show(). - Your dialog launched from within that main window, so control returns to it after the dialog is dismissed.
With this structure in place, your dialogs will open and close without affecting the rest of your application. If you want to open additional windows beyond dialogs, take a look at our guide on creating multiple windows in PyQt6.
PyQt/PySide 1:1 Coaching with Martin Fitzpatrick
Save yourself time and frustration. Get one on one help with your Python GUI projects. Working together with you I'll identify issues and suggest fixes, from bugs and usability to architecture and maintainability.