Reputation: 957
I am currently coding an application using the Qt4 python bindings that requires the user to provide login credentials. At startup of my application I show a modal dialog in which the user can enter their data. Since the application cannot provide useful services when the user is not logged in, I want to close the app if the user clicks the cancel button.
So, if the dialog returns a negative result, I just call the close()
method of my QMainWindow
. Normally this leads to the exit of the application since there are no interactable windows any more.
However, if the modal Dialog has been shown before, the application simply continues to run and I have to kill it manually.
Below is the code for an minimal example
main.py:
import sys
from PyQt4.QtGui import QApplication
from MyMainWindow import MyMainWindow
app = QApplication(sys.argv)
window = MyMainWindow()
window.show()
app.exec_()
print "Terminated"
MyMainWindow.py:
from PyQt4.QtGui import QMainWindow
from PyQt4 import QtGui
from MyDialog import MyDialog
class MyMainWindow(QMainWindow):
def __init__(self, parent=None):
QMainWindow.__init__(self, parent)
self.setWindowTitle("Close App Test")
self.centralwidget = QtGui.QWidget(self)
self.verticalLayout = QtGui.QVBoxLayout(self.centralwidget)
self.closeButton = QtGui.QPushButton(self.centralwidget)
self.closeButton.setText("Close")
self.closeButton.clicked.connect(self.exit)
def show(self):
QMainWindow.show(self)
myDialog = MyDialog(self)
res = myDialog.exec_()
if res == 0:
self.exit()
else:
print "Continue"
def exit(self):
self.close()
MyDialog.py:
from PyQt4.QtGui import QDialog
from PyQt4 import QtGui
class MyDialog(QDialog):
def __init__(self, parent = None):
QDialog.__init__(self, parent)
self.setWindowTitle("Modal Dialog")
self.resize(200, 50)
self.closeButton = QtGui.QPushButton(self)
self.closeButton.setText("Close")
self.closeButton.move(10, 10)
self.otherButton = QtGui.QPushButton(self)
self.otherButton.setText("Do Nothing")
self.otherButton.move(100, 10)
self.closeButton.clicked.connect(self.reject)
self.otherButton.clicked.connect(self.accept)
If the Close button on the modal dialog is clicked, the application continues to run even if all windows are closed. If the "Do Nothing" button is clicked, and the application is closed with the close button on the main window, everything works as expected and the application terminates.
I cannot really see the difference between both cases, since each time I just call close
on the main window. I can just assume that I have errors in handling the modal dialog. I even tried tinkering around with myDialog.close()
, myDialog.destroy()
, as well as the quitOnClose
and deleteOnClose
window attributes without any positive effects.
Any help is appreciated.
Upvotes: 0
Views: 2136
Reputation: 86
self.exit() is called before app.exec_() if the Close button on the modal dialog is clicked, so the application continues to run. self.exit() should be called when the main event loop is running.
The following is a possible solution for the case:
from PyQt4.QtGui import QMainWindow
from PyQt4 import QtGui
from pyQt4 import QtCore
from MyDialog import MyDialog
class MyMainWindow(QMainWindow):
def __init__(self, parent=None):
QMainWindow.__init__(self, parent)
self.setWindowTitle("Close App Test")
self.centralwidget = QtGui.QWidget(self)
self.verticalLayout = QtGui.QVBoxLayout(self.centralwidget)
self.closeButton = QtGui.QPushButton(self.centralwidget)
self.closeButton.setText("Close")
self.closeButton.clicked.connect(self.exit)
def login(self):
myDialog = MyDialog(self)
res = myDialog.exec_()
if res == 0:
self.exit()
else:
print "Continue"
def show(self):
QMainWindow.show(self)
QtCore.QTimer.singleShot(0, self.login)
def exit(self):
self.close()
Upvotes: 1