wxPython 事件处理
与顺序执行的控制台模式应用程序不同,基于GUI的应用程序是事件驱动的。函数或方法根据用户的操作(如点击按钮、从集合中选择项目或鼠标点击等)来执行,这些操作被称为事件。
运行时发生的事件的相关数据存储在一个从wx.Event派生的子类对象中。显示控件(如Button)是特定类型事件的源,会生成与其关联的Event类对象。例如,点击按钮会发送一个wx.CommandEvent。这个事件数据会分发到程序中的事件处理方法。wxPython有许多预定义的事件绑定器。一个 事件绑定器 封装了一个特定小部件(控件)、与其关联的事件类型和事件处理方法之间的关系。
例如,要在按钮的点击事件上调用程序的 OnClick()方法 ,需要使用以下语句:
self.b1.Bind(EVT_BUTTON, OnClick)
Bind()方法 被所有显示对象从wx.EvtHandler类继承。这里的EVT_.BUTTON是绑定器,它将按钮点击事件与OnClick()方法关联起来。
示例
在下面的示例中,由拖动顶层窗口(这里是一个wx.Frame对象)引起的MoveEvent与 OnMove()方法 使用wx.EVT_MOVE绑定器连接起来。代码显示一个窗口。如果使用鼠标移动它,它的瞬时坐标将显示在控制台上。
import wx
class Example(wx.Frame):
def __init__(self, *args, **kw):
super(Example, self).__init__(*args, **kw)
self.InitUI()
def InitUI(self):
self.Bind(wx.EVT_MOVE, self.OnMove)
self.SetSize((250, 180))
self.SetTitle('Move event')
self.Centre()
self.Show(True)
def OnMove(self, e):
x, y = e.GetPosition()
print "current window position x = ",x," y= ",y
ex = wx.App()
Example(None)
ex.MainLoop()
以上代码产生以下输出 –
current window position x = 562 y = 309
current window positio x = 562 y = 309
current window positio x = 326 y = 304
current window positio x = 384 y = 240
current window positio x = 173 y = 408
current window positio x = 226 y = 30
current window positio x = 481 y = 80
wx.Event中继承的一些子类如下表所示-
下面是最常用的wx.Event事件
序号 | 事件与说明 |
---|---|
1 | wxKeyEvent 在按下或释放键时发生 |
2 | wxPaintEvent 当窗口内容需要重绘时生成 |
3 | wxMouseEvent 包含与鼠标操作相关的任何事件的数据,如鼠标按下或拖动 |
4 | wxScrollEvent 与可滚动控件(如wxScrollbar和wxSlider)相关联 |
5 | wxCommandEvent 包含由多个小部件(如按钮、对话框、剪贴板等)生成的事件数据 |
6 | wxMenuEvent 与菜单相关的不包括菜单命令按钮点击的事件 |
7 | wxColourPickerEvent 由wxColourPickerCtrl生成的事件 |
8 | wxDirFilePickerEvent 由FileDialog和DirDialog生成的事件 |
wxPython中的事件分为两种类型。基本事件和命令事件。基本事件限于其发生的窗口。大多数wxWidgets生成命令事件。命令事件可以传播到窗口或在类层次结构中位于源窗口上方的窗口。
示例
以下是一个事件传播的简单示例。完整的代码如下-
import wx
class MyPanel(wx.Panel):
def __init__(self, parent):
super(MyPanel, self).__init__(parent)
b = wx.Button(self, label = 'Btn', pos = (100,100))
b.Bind(wx.EVT_BUTTON, self.btnclk)
self.Bind(wx.EVT_BUTTON, self.OnButtonClicked)
def OnButtonClicked(self, e):
print 'Panel received click event. propagated to Frame class'
e.Skip()
def btnclk(self,e):
print "Button received click event. propagated to Panel class"
e.Skip()
class Example(wx.Frame):
def __init__(self,parent):
super(Example, self).__init__(parent)
self.InitUI()
def InitUI(self):
mpnl = MyPanel(self)
self.Bind(wx.EVT_BUTTON, self.OnButtonClicked)
self.SetTitle('Event propagation demo')
self.Centre()
self.Show(True)
def OnButtonClicked(self, e):
print 'click event received by frame class'
e.Skip()
ex = wx.App()
Example(None)
ex.MainLoop()
在上面的代码中,有两个类。
MyPanel ,一个wx.Panel的子类和Example,一个wx.Frame的子类,它是程序的顶级窗口。一个按钮被放置在面板中。
这个按钮对象被绑定到一个事件处理函数btnclk(),它将其传播到父类(在这种情况下是MyPanel)。按钮点击会产生一个 CommandEvent ,可以通过Skip()方法传播到其父类。
MyPanel类对象还将接收到的事件绑定到另一个处理函数OnButtonClicked()。这个函数转发给它的父类,Example类。上面的代码产生以下输出 –
Button received click event. Propagated to Panel class.
Panel received click event. Propagated to Frame class.
Click event received by frame class.