生成QCloseEvent却无法关闭QMainWindow
我正在尝试做一件很简单的事情:在菜单栏中添加一个带有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 个回答
关闭事件并不是让窗口真的关闭,而是在窗口已经开始关闭时触发的。要真正关闭窗口,你需要调用self.close()
,这样会引发一个QCloseEvent
事件。所以你只需要这样做:
exit_action.triggered.connect(self.close)
close
的文档描述了close
和closeEvent
之间的关系:
bool QWidget.close (self)
这个方法也是一个Qt的槽函数,C++的签名是bool close()。
关闭这个小部件。如果小部件成功关闭,返回true;否则返回false。
首先,它会给小部件发送一个QCloseEvent。如果小部件接受这个关闭事件,它就会被隐藏。如果小部件忽略这个事件,那就什么都不会发生。QWidget.closeEvent()的默认实现是接受关闭事件。
文档上说,
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_())