wxPython in Action (EVT_CLOSE)当关闭一个框架时都发生了什么?

本文深入探讨了wxPython中窗口部件的关闭过程,包括用户触发关闭和系统触发关闭的情况,以及如何在关闭过程中管理外部资源。同时,介绍了如何处理系统自己的关闭事件,以及关闭窗口部件时的注意事项。
 当你关闭一个框架时,它最终消失了。除非这个框架被明确地告诉不关闭。换句话说,那关闭不是直接了当的。在wxPython的窗口部件关闭体系之后的用意是,给正在关闭的窗口部件充足的机会来关闭或释放它所占用任何非wxPython资源。如果你占用了某种昂贵的外部资源,如一个大的数据结构或一个数据库连接,那么该意图是特别受欢迎的。

诚然,在C++ wxWidgets世界里,由于C++不为你管理内在分配的清理工作,管理资源是更严肃的问题。在wxPython中,对于多步的关闭过程的显式需求就很少,但它对于在过程中使用额外的钩子仍然是有用的。(随便说一下,我们在这一节中从单词“框架”切换到单词“窗口部件”是故意的——因为在本节中的所有内容都适用于所有顶级窗口部件,如框架或对话框)。

何时用户触发关闭过程

关闭过程最常由用户触发,如敲击一个关闭框或选择系统菜单中的关闭项或当应用程序响应其它某个事件而调用框架的Close方法。当上述情况发生时,wxPython架构引发一个EVT_CLOSE事件。像wxPython 架构中的其它别的事件一样,你可以在绑定一个事件处理器以便一个EVT_CLOSE事件发生时调用。

如果你不声明你自己的事件处理器,那么默认的行为将被调用。默认的行为对于框架和对话框是不同的。

1、默认情况下,框架处理器调用Destroy()方法并删除该框架和它的所有的组件。

2、默认情况下,对话框的关闭处理器不销毁该对话框——它仅仅模拟取消按钮的按下,并隐藏对话框。该对话框对象仍继续存在在内存中。因此,如果需要的话,应用程序可以从它的数据输入部件获取值。当应用程序完成了对对话框的使用后,应该调用对话框的Destroy()方法。

如果你编写你自己的关闭处理器,那么你可以使用它来关闭或删除任何外部的资源,但是,如果你选择去删除框架的话,显式地调用Destroy()方法是你的责任。尽管Destroy()经常被Close()调用,但是只调用Close()方法不能保证框架的销毁。在一定的情形下,决定不销毁框架是完全可以的,如当用户取消了关闭。然而,你仍然需要一个方法来销毁该框架。如果你选择不去销毁窗口,那么调用关闭事件的wx.CloseEvent.Veto()方法来通知相关部分:框架拒绝关闭,是一个好的习惯。

如果你选择在你的程序的别处而非关闭处理器中关闭你的框架,例如从一个不同的用户事件像一个菜单项,那么我们建议使用的机制是调用框架的Close()方法。这将启动一个和系统关闭行为相同的过程。如果你要确保框架一定被删除,那么你可以直接调用Destroy()方法;然而,如果你这样做了,可能会导致框架所管理的资源或数据没有被释放或保存。

什么时候系统触发关闭过程

如果关闭事件是由系统自己触发的,对于系统关闭或类似情况,你也有一种办法管理该事件。wx.App 类接受一个EVT_QUERY_END_SESSION事件,如果需要的话,该事件使你能够否决应用程序的关闭,如果所有运行的应用已经批准了系统或GUI环境的关闭的话,那么随后会有一个EVT_END_SESSION事件。你选择去否决关闭的行为是与依赖于具体系统的。

最后,值得注意的是,调用一个窗口部件的Destroy()方法不意味该部件被立即销毁。销毁实际上是当事件循环在未来空闲时(任何未被处理的事件被处理之后)才被处理的。这就防止了处理已不存在的窗口部件的事件。
wxPython中,除了 `EVT_PAINT` 事件外,与Panel相关的常用事件如下: ### 焦点事件 焦点事件(`wx.FocusEvent`)用于处理组件获得或失去焦点的情况。例如,当用户使用Tab键切换焦点,或者鼠标点击不同组件,会触发此类事件。可以使用 `EVT_SET_FOCUS` 和 `EVT_KILL_FOCUS` 来分别处理组件获得和失去焦点的事件。示例代码如下: ```python import wx class MyPanel(wx.Panel): def __init__(self, parent): wx.Panel.__init__(self, parent) self.Bind(wx.EVT_SET_FOCUS, self.on_set_focus) self.Bind(wx.EVT_KILL_FOCUS, self.on_kill_focus) def on_set_focus(self, event): print("Panel got focus.") event.Skip() def on_kill_focus(self, event): print("Panel lost focus.") event.Skip() app = wx.App() frame = wx.Frame(None, title="Focus Event Example") panel = MyPanel(frame) frame.Show() app.MainLoop() ``` ### 键盘事件 键盘事件(`wx.KeyEvent`)用于处理用户按下或释放键盘按键的情况。可以使用 `EVT_KEY_DOWN` 和 `EVT_KEY_UP` 来分别处理按键按下和释放的事件。示例代码如下: ```python import wx class MyPanel(wx.Panel): def __init__(self, parent): wx.Panel.__init__(self, parent) self.Bind(wx.EVT_KEY_DOWN, self.on_key_down) self.Bind(wx.EVT_KEY_UP, self.on_key_up) def on_key_down(self, event): key_code = event.GetKeyCode() print(f"Key {key_code} was pressed.") event.Skip() def on_key_up(self, event): key_code = event.GetKeyCode() print(f"Key {key_code} was released.") event.Skip() app = wx.App() frame = wx.Frame(None, title="Keyboard Event Example") panel = MyPanel(frame) frame.Show() app.MainLoop() ``` ### 鼠标事件 鼠标事件(`wx.MouseEvent`)用于处理用户使用鼠标进行的各种操作,如点击、移动、拖动等。常用的鼠标事件包括 `EVT_LEFT_DOWN`、`EVT_LEFT_UP`、`EVT_MOTION` 等。示例代码如下: ```python import wx class MyPanel(wx.Panel): def __init__(self, parent): wx.Panel.__init__(self, parent) self.Bind(wx.EVT_LEFT_DOWN, self.on_left_down) self.Bind(wx.EVT_LEFT_UP, self.on_left_up) self.Bind(wx.EVT_MOTION, self.on_mouse_move) def on_left_down(self, event): pos = event.GetPosition() print(f"Left mouse button down at {pos}.") event.Skip() def on_left_up(self, event): pos = event.GetPosition() print(f"Left mouse button up at {pos}.") event.Skip() def on_mouse_move(self, event): if event.Dragging() and event.LeftIsDown(): pos = event.GetPosition() print(f"Mouse dragging at {pos}.") event.Skip() app = wx.App() frame = wx.Frame(None, title="Mouse Event Example") panel = MyPanel(frame) frame.Show() app.MainLoop() ``` ### 滚动事件 滚动事件用于处理滚动条的操作,如 `EVT_SCROLLWIN_THUMBRELEASE` 和 `EVT_SCROLLWIN_THUMBTRACK` 等。在 `EVT_SCROLLWIN_THUMBRELEASE` 事件中,需要对 `EVT_SCROLLWIN_THUMBTRACK` 事件中改变的位置做出回应,例如取得拖曳滚动条的位置并设置滚动位置[^4]。 ### 关闭事件 关闭事件(`wx.CloseEvent`)是一个基础事件,意味着它不会向上传播。当用户尝试关闭包含Panel的窗口,会触发该事件。可以使用 `EVT_CLOSE` 来处理窗口关闭事件。示例代码如下: ```python import wx class MyPanel(wx.Panel): def __init__(self, parent): wx.Panel.__init__(self, parent) class MyFrame(wx.Frame): def __init__(self): wx.Frame.__init__(self, None, title="Close Event Example") panel = MyPanel(self) self.Bind(wx.EVT_CLOSE, self.on_close) def on_close(self, event): print("Window is closing.") self.Destroy() app = wx.App() frame = MyFrame() frame.Show() app.MainLoop() ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值