背景: 对于单击“x”按钮时隐藏自身(或最小化它,或仅关闭“主窗口”)而不是关闭整个应用程序的应用程序来说,这是很常见的。在Mac中,关闭窗口是“command+w”,而关闭应用程序是“command+q”。他们是不同的。
问题:
closeEvent
不够。在 PyQT5 中,我们可以在任何 QWindow/QDialog/QWidget 中挂钩 closeEvent 并拒绝该事件。我们可以通过self.hide()
隐藏窗口。
def closeEvent(self, event):
event.reject()
self.hide()
但是,如果我们这样做,窗口将变得无法停止,因为其他关闭方式(Command+Q 或右键单击图标然后退出或通过菜单栏退出)都被阻止。 (这很有趣,因为应用程序无论如何都无法关闭。)
潜在的解决方案:
如何在pyqt4 python中编写窗口关闭(X)按钮的事件,但与“如何使用Qt禁用窗口的关闭按钮”的所谓“重复”完全不同
[1]。这不是一个大问题,但却是相关的。一旦窗口被隐藏,我们需要一个“单击任务栏/停靠栏中的图标”事件来显示它。是否有一些对象绑定到该事件?
WA_QuitOnClose
设置为 False。以下对我有用:
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
if __name__ == '__main__':
app = QApplication(sys.argv)
window = QMainWindow()
window.setCentralWidget(QWidget())
window.setAttribute(Qt.WA_QuitOnClose, False)
QShortcut(QKeySequence.Close, window, window.close)
window.show()
sys.exit(app.exec_())
我认为事件链是: 应用程序关闭 (19) -> 窗口关闭 (19) -> AboutToQuit
因此,如果窗口关闭被阻止,AboutToQuit 中没有任何帮助。我们只需要捕获上游事件,应用程序关闭。
class MyApplication(QApplication):
def event(self, e):
if e.type() == 19: # Close event
sys.exit() # Or we can do other things to "force close"
class MyWindow(QMainWindow):
def closeEvent(self, e):
e.ignore()
if __name__ == '__main__':
app = MyApplication(sys.argv)
window = MyWindow()
window.show()
sys.exit(app.exec_())
import tkinter as tk
def run_gui_example():
global root
# Create the main window
root = tk.Tk()
root.title("Simple GUI Example")
# return root
root.protocol("WM_DELETE_WINDOW", on_close) #Hide window instead of close it
# Start the GUI event loop
root.mainloop()
def on_close():
root.withdraw()
print('window hidden, program running')
# Call the function to run the GUI example
run_gui_example()