生成QCloseEvent却无法关闭QMainWindow

1 投票
2 回答
5816 浏览
提问于 2025-04-20 09:11

我正在尝试做一件很简单的事情:在菜单栏中添加一个带有Exit(退出)功能的选项,这样当我选择它时,就能关闭一个QMainWindow(主窗口)。但是,当我实际点击Exit时,应用程序并没有关闭。以下是一个简单的示例:

from PyQt4 import QtGui, QtCore

import sys

class Window(QtGui.QMainWindow):

    def __init__(self, parent=None):
        super(Window, self).__init__(parent)
        widget = QtGui.QWidget()
        self.setCentralWidget(widget)

        self.menu_bar = QtGui.QMenuBar(self)
        menu = self.menu_bar.addMenu('File')

        exit_action = QtGui.QAction('Exit', self)
        exit_action.triggered.connect(lambda:
            self.closeEvent(QtGui.QCloseEvent()))
        menu.addAction(exit_action)
        self.setMenuBar(self.menu_bar)

    def closeEvent(self, event):
        print('Calling')
        print('event: {0}'.format(event))
        event.accept()


app = QtGui.QApplication(sys.argv)
form = Window()
form.show()
sys.exit(app.exec_())

让我感到困惑的是,当我从File(文件)菜单中点击Exit时,我得到了以下输出:

调用

事件: <PyQt4.QtGui.QCloseEvent object at 0x024B7348>

但是应用程序并没有退出。

如果我点击右上角的X,我得到的输出也是一样的(包括事件对象的内存地址):

调用

事件: <PyQt4.QtGui.QCloseEvent object at 0x024B7348>

而应用程序却确实退出了。

这是在Windows 7 64位系统上,使用的是Python 2.7.2和PyQt 4.8.6。

2 个回答

1

关闭事件并不是让窗口真的关闭,而是在窗口已经开始关闭时触发的。要真正关闭窗口,你需要调用self.close(),这样会引发一个QCloseEvent事件。所以你只需要这样做:

 exit_action.triggered.connect(self.close)

close文档描述了closecloseEvent之间的关系:

bool QWidget.close (self)

这个方法也是一个Qt的槽函数,C++的签名是bool close()。

关闭这个小部件。如果小部件成功关闭,返回true;否则返回false。

首先,它会给小部件发送一个QCloseEvent。如果小部件接受这个关闭事件,它就会被隐藏。如果小部件忽略这个事件,那就什么都不会发生。QWidget.closeEvent()的默认实现是接受关闭事件。

1

文档上说

QCloseEvent类包含了一些参数,用来描述关闭事件。

关闭事件是当用户想要关闭某个窗口时发送的,通常是通过从窗口菜单中选择“关闭”,或者点击标题栏上的X按钮来实现的。当你用QWidget.close()这个方法来编程关闭一个窗口时,也会发送关闭事件。

你可以直接使用关闭信号,而不是通过QCloseEvent,请使用self.close()来关闭。

from PyQt4 import QtGui, QtCore

import sys

class Window(QtGui.QMainWindow):

    def __init__(self, parent=None):
        super(Window, self).__init__(parent)
        widget = QtGui.QWidget()
        self.setCentralWidget(widget)

        self.menu_bar = QtGui.QMenuBar(self)
        menu = self.menu_bar.addMenu('File')

        exit_action = QtGui.QAction('Exit', self)
        exit_action.triggered.connect(self.close)
        menu.addAction(exit_action)
        self.setMenuBar(self.menu_bar)

    def closeEvent(self, event):
        print('Calling')
        print('event: {0}'.format(event))
        event.accept()


app = QtGui.QApplication(sys.argv)
form = Window()
form.show()
sys.exit(app.exec_())

撰写回答