通过模式对话框关闭PyQt应用程序



我目前正在使用Qt4 python绑定编写一个应用程序,该绑定要求用户提供登录凭据。在应用程序启动时,我会显示一个模式对话框,用户可以在其中输入数据。由于用户未登录时应用程序无法提供有用的服务,因此如果用户单击"取消"按钮,我希望关闭该应用程序。

因此,如果对话框返回一个否定的结果,我只调用QMainWindowclose()方法。通常情况下,这会导致应用程序退出,因为不再有可交互的窗口。

但是,如果以前显示过模态对话框,那么应用程序将继续运行,我必须手动终止它。

以下是的最小示例代码

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)

如果单击模式对话框上的"关闭"按钮,即使关闭了所有窗口,应用程序也会继续运行。如果单击"Do Nothing"按钮,并使用主窗口上的关闭按钮关闭应用程序,则一切正常,应用程序终止。

我真的看不出这两种情况之间的区别,因为每次我都只是在主窗口上调用close。我可以假设我在处理模态对话框时有错误。我甚至试着修改myDialog.close()myDialog.destroy()以及quitOnClosedeleteOnClose窗口属性,但没有任何积极影响。

感谢您的帮助。

self.exit()在app.exec_()之前调用,如果单击模式对话框上的"关闭"按钮,则应用程序将继续运行。self.exit()应该在主事件循环运行时调用。

以下是该情况的可能解决方案:

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()

最新更新