PyQt:单击X不会触发closeEvent

Woo*_*e88 10 python pyqt pyqt4

我是PyQt的新手,试图开发简单的应用程序.我用Qt设计师设计了简单的ui.如果用户在单击X或退出''按钮或从菜单中选择退出时确实要退出应用程序,我想要额外确认.

这是代码:

import sys
from PyQt4 import QtGui, QtCore, uic

class MainWindow(QtGui.QMainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)

        self.ui = uic.loadUi('main_window.ui')
        self.ui.show()

        self.ui.btnExit.clicked.connect(self.close)
        self.ui.actionExit.triggered.connect(self.close)

    def closeEvent(self, event):
        print("event")
        reply = QtGui.QMessageBox.question(self, 'Message',
            "Are you sure to quit?", QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)

        if reply == QtGui.QMessageBox.Yes:
            event.accept()
        else:
            event.ignore()


def main():
    app = QtGui.QApplication(sys.argv)
    win = MainWindow()
    sys.exit(app.exec_())


if __name__ == "__main__":
    main()
Run Code Online (Sandbox Code Playgroud)

问题是:

  • 当我在主窗口上单击X时,closeEvent函数不会触发
  • 当我单击"退出"按钮或选择"从菜单退出"时,将
    调用该功能,但单击"是"不会关闭应用程序.

我在SO上发现了一些问题并搜索了教程,但没有任何内容涉及这样的问题.我究竟做错了什么?

Ava*_*ris 15

请注意,您正在做:

self.ui = uic.loadUi('main_window.ui')
self.ui.show()
Run Code Online (Sandbox Code Playgroud)

您的实际窗口(实例属性ui) win.不是它win自己.它没有closeEvent实现.

loadUi可以.ui在实例中加载文件.

PyQt4.uic.loadUi(uifile[, baseinstance=None[, package='']])
Run Code Online (Sandbox Code Playgroud)

你应该使用它.有了它,你的代码将是:

import sys
from PyQt4 import QtGui, QtCore, uic

class MainWindow(QtGui.QMainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)

        uic.loadUi('main_window.ui', self)

        self.btnExit.clicked.connect(self.close)
        self.actionExit.triggered.connect(self.close)

    def closeEvent(self, event):
        print("event")
        reply = QtGui.QMessageBox.question(self, 'Message',
            "Are you sure to quit?", QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)

        if reply == QtGui.QMessageBox.Yes:
            event.accept()
        else:
            event.ignore()


def main():
    app = QtGui.QApplication(sys.argv)
    win = MainWindow()
    win.show()
    sys.exit(app.exec_())


if __name__ == "__main__":
    main()
Run Code Online (Sandbox Code Playgroud)

注意:我不喜欢进show__init__.明确更好.所以,我把它移到了main.随意修改它.


小智 11

它适用于我,只需添加此行

self.ui.closeEvent = self.closeEvent
Run Code Online (Sandbox Code Playgroud)

所以你的代码将是:

import sys
from PyQt4 import QtGui, QtCore, uic

class MainWindow(QtGui.QMainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)

        self.ui = uic.loadUi('main_window.ui')
        self.ui.closeEvent = self.closeEvent
        self.ui.show()

        self.ui.btnExit.clicked.connect(self.close)
        self.ui.actionExit.triggered.connect(self.close)

    def closeEvent(self, event):
        print("event")
        reply = QtGui.QMessageBox.question(self, 'Message',
            "Are you sure to quit?", QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)

        if reply == QtGui.QMessageBox.Yes:
            event.accept()
        else:
            event.ignore()


def main():
    app = QtGui.QApplication(sys.argv)
    win = MainWindow()
    sys.exit(app.exec_())


if __name__ == "__main__":
    main()
Run Code Online (Sandbox Code Playgroud)