Python PyQt:单击 X 不会触发 closeEvent
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14834494/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
PyQt: clicking X doesn't trigger closeEvent
提问by Wookie88
I'm a total newbie in PyQt trying to develop simple application. I have designed simple ui with Qt-designer. I want extra confirmation if the user really want to exit application when clicking X or ,,Exit'' button or choosing Exit from menu.
我是 PyQt 的新手,试图开发简单的应用程序。我用 Qt-designer 设计了简单的 ui。如果用户真的想在单击 X 或 ,,Exit'' 按钮或从菜单中选择退出时退出应用程序,我需要额外的确认。
Here's the code:
这是代码:
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()
The problem is that:
问题在于:
- When I click X on main window the closeEvent function doesn't trigger
- When I click Exit button or choose ,,Exit'' from menu, the function
is called, but clicking Yes doesn't close application.
- 当我在主窗口上单击 X 时,closeEvent 函数不会触发
- 当我单击退出按钮或从菜单中选择 ,,Exit'' 时,该函数
被调用,但单击是不会关闭应用程序。
I have found some questions on SO and searched for tutorials, but nothing covered such problem. What am I doing wrong?
我在 SO 上发现了一些问题并搜索了教程,但没有涵盖此类问题。我究竟做错了什么?
采纳答案by Avaris
Note that you're doing:
请注意,您正在执行以下操作:
self.ui = uic.loadUi('main_window.ui')
self.ui.show()
Your actualwindow is an instance attribute (ui) insidewin. Not the winitself. And it doesn't have closeEventimplemented.
您的实际窗口是内部的实例属性 ( ui) 。不是本身。它没有实施。winwincloseEvent
loadUican load the .uifile inside an instance.
loadUi可以.ui在实例中加载文件。
PyQt4.uic.loadUi(uifile[, baseinstance=None[, package='']])
You should use that. With that, your code would be:
你应该用那个。这样,您的代码将是:
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()
Note: I'm not a fan of showing the window in __init__. Explicit is better. So, I moved that to main. Feel free to modify it.
注意:我不喜欢show在__init__. 明确的更好。所以,我把它移到了main. 随意修改它。
回答by LtWorf
From the designer you can connect events to the main window, and add new slots to it in the designer, then just implement the methods in python and the event->slot connection will be done automatically.
从设计器中,您可以将事件连接到主窗口,并在设计器中为其添加新槽,然后只需在 python 中实现方法,事件->槽连接将自动完成。
回答by Anggun Pribadi
it works for me, just adding this line
它对我有用,只需添加这一行
self.ui.closeEvent = self.closeEvent
so your code would be:
所以你的代码是:
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()
回答by Natesh bhat
Another simple solution for this is using the app.aboutToQuit.connect(self.close_event)to run the code in the closeEventfunction whenever the user clicks the close button.
另一个简单的解决方案是在用户单击关闭按钮时使用app.aboutToQuit.connect(self.close_event)运行closeEvent函数中的代码。
Sample code here
示例代码在这里
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
#--------------------------------------------------------------------------------
app.aboutToQuit.connect(self.closeEvent) #this line is what ur looking for !!!!!!
#--------------------------------------------------------------------------------
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle('Demo')
#{______________________________________
def closeEvent(self):
#Your code here
print('User has pressed the close button')
import sys
sys.exit(0)
#}______________________________________
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
MainWindow = QtGui.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)

