wxPython – 事件处理
与控制台模式的应用程序不同,它是以顺序方式执行的,而基于GUI的应用程序是事件驱动的。函数或方法是根据用户的操作(如点击按钮、从集合中选择项目或鼠标点击等)来执行的,称为事件。
与应用程序运行期间发生的事件有关的数据被存储为派生自 wx.Event 的子类的对象 。 一个显示控件(如Button)是一个特定类型的事件的来源,并产生一个与之相关的Event类的对象。例如,点击一个按钮会发出一个wx.CommandEvent。这个事件数据被派发到程序中的事件处理方法。一个 事件绑定器 封装了一个特定的部件(控件)、其相关事件类型和事件处理方法之间的关系。
例如,要在一个按钮的点击事件中调用程序的 OnClick()方法 ,需要以下语句 —
self.b1.Bind(EVT_BUTTON, OnClick)
Bind()方法 被所有来自wx.EvtHandler类的显示对象继承了。这里的EVT_.BUTTON是一个绑定器,它将按钮的点击事件与OnClick()方法联系起来。
例子
在下面的例子中,MoveEvent,由拖动顶层窗口引起–在本例中是一个wx.Frame对象–被使用wx.EVT_MOVE绑定器连接到 OnMove()方法 。该代码显示了一个窗口。如果用鼠标移动它,它的瞬时坐标会显示在控制台。
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()
上述代码产生了以下输出 —
下表列出了一些从wx.Event继承的子类—
下面给出了wx.Event 最常用的事件
S.N | 事件和描述 |
---|---|
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子类,是程序的顶层窗口。一个按钮被放置在面板中。
这个Button对象被绑定到一个事件处理程序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.