实战wxPython系列-014

wxpython安装过程(wxPython-系统常用事件)(1)

在wxPython中,包含了GUI应用所必须的一些常用事件,这些事件是构建一个GUI应用所必不可少的,比如绘制事件(wx.PaintEvent),焦点事件(wx.FocusEvent), 键盘事件(wx.KeyEvent),鼠标事件(wx.MouseEvent)等等。

一、绘制事件(wx.PaintEvent)

当窗口的内容需要重新绘制的时候,比如当我们调整窗口大小或者最大化的时候,会发送一个绘制事件(Paint Event)。当然我们也可以通过程序来触发绘制事件,比如,在调用Set Label()方法来修改wx.StaticText控件的文字信息时,就会触发绘制事件。注意,窗口最小化不会触发绘制事件。

wxpython安装过程(wxPython-系统常用事件)(2)

图1:wx.PaintEvent类继承关系

#绘制事件(wx.PaintEvent) import wx class SamplePaintEvent(wx.Frame): def __Init__(self, *args, **kw): super(SamplePaintEvent, self).__init__(*args, **kw) self.InitUi() def InitUi(self): self.count = 0 self.Bind(wx.EVT_PAINT, self.OnPaint) self.SetTitle("实战wxPython: 绘制事件") self.SetSize(400, 280) self.Centre() def OnPaint(self, e): self.count = 1 dc = wx.PaintDC(self) text = "Number of paint events: {0}".format(self.count) #从客户区指定像素点(20, 20)显示text dc.DrawText(text, 20, 20) def main(): app = wx.App() sample = SamplePaintEvent(None) sample.Show() app.MainLoop() if __name__ == "__main__": main()

在上面的例子中,我们对绘制事件进行计数,并在窗口中打印出计数值。该示例运行结果如图2所示:

wxpython安装过程(wxPython-系统常用事件)(3)

图2:PaintEvent演示

二、焦点事件(wx.FocusEvent)

当窗口的焦点发生变化时,将发送焦点事件。焦点表明了当前应用中被选中的控件(widget),当控件被选中时,从键盘输入或从剪贴板拷入的文本将发送到该控件。又两个事件和焦点相关,它们是wx.EVT_SET_FOCUS和wx.EVT_KILL_FOCUS。当一个控件获得焦点时,就会触发wx.EVT_SET_FOCUS事件,当一个控件失去焦点时,则会触发wx.EVT_KILL_FOCUS事件。通过点击或者键盘按键比如Tab键或者Shift Tab键可以在控件之间切换焦点。

wxpython安装过程(wxPython-系统常用事件)(4)

图3:wx.FocusEvent类继承关系

#焦点事件(wx.FocusEvent) import wx class MyWindow(wx.Panel): def __init__(self, parent): super(MyWindow, self).__init__(parent) #画笔颜色 self.color = "#b3b3b3" #绑定事件处理 self.Bind(wx.EVT_PAINT, self.OnPaint) self.Bind(wx.EVT_SIZE, self.OnSize) self.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus) self.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus) def OnPaint(self, e): dc = wx.PaintDC(self) # 设置画笔 dc.SetPen(wx.Pen(self.color)) # 获得客户区的尺寸 x,y = self.GetSize() # 绘制一个矩形 dc.DrawRectangle(0, 0, x, y) def OnSize(self, e): #当客户区发生改变时,刷新客户区 self.Refresh() def OnSetFocus(self, e): #当进入焦点区域时,将画笔颜色设置为红色并重绘客户区 self.color = "#ff0000" self.Refresh() def OnKillFocus(self, e): #当离开焦点区域时,将画笔颜色恢复为初始颜色并重绘客户区 self.color = "#b3b3b3" self.Refresh() class SampleFocusEvent(wx.Frame): def __init__(self, *args, **kw): super(SampleFocusEvent, self).__init__(*args, **kw) self.InitUi() def InitUi(self): #创建一个2x2网格布局 grid = wx.GridSizer(2, 2, 10, 10) grid.AddMany([(MyWindow(self), 0, wx.EXPAND|wx.TOP|wx.LEFT, 9), (MyWindow(self), 0, wx.EXPAND|wx.TOP|wx.RIGHT, 9), (MyWindow(self), 0, wx.EXPAND|wx.BOTTOM|wx.LEFT, 9), (MyWindow(self), 0, wx.EXPAND|wx.BOTTOM|wx.RIGHT, 9)]) self.SetSizer(grid) self.SetSize(400, 280) self.SetTitle("实战wxPython: 焦点事件") self.Centre() def main(): app = wx.App() sample = SampleFocusEvent(None) sample.Show() app.MainLoop() if __name__ == "__main__": main()

在上面的例子中,创建了4个panel,获得焦点的panel被高亮显示。

self.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus) self.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus)

上面的代码把两个焦点事件绑定到事件处理函数。

在panel获得焦点时,在OnPaint()方法中将绘制一个红色的边框。上面的例子运行效果如图4所示:

wxpython安装过程(wxPython-系统常用事件)(5)

图4:FocusEvent演示

三、键盘事件(wx.KeyEvent)

键盘事件类包含有关按键和释放事件的信息。

键盘事件所携带的主要信息是正在按下或释放的键。它可以使用GetUnicodeKey, GetKeyCode或GetRawKeyCode函数之一来访问。对于可打印字符,应该使用GetUnicodeKey,因为它适用于任何键,包括使用国家键盘布局时可以输入的非latin -1字符。GetKeyCode应该用于处理与wx对应的特殊字符(如光标箭头键或HOME或INS等)。

虽然因为兼容性要求,GetKeyCode还返回Latin-1键的字符代码,但它一般不适用于Unicode字符,并且对于任何非Latin-1键将返回WXK_NONE。如果GetUnicodeKey和GetKeyCode都返回WXK_NONE,那么该键没有WXK_xxx映射,GetRawKeyCode可以用来区分键,但原始键代码是特定于平台上的。出于这些原因,建议总是使用GetUnicodeKey,只有当GetUnicodeKey返回WXK_NONE时才返回GetKeyCode,这意味着该事件对应于一个不可打印的特殊键,如果GetKeyCode也返回WXK_NONE,则可考虑检查GetRawKeyCode,或者直接忽略该键。

当我们在键盘上按下按钮时,一个 wx.KeyEvent 会被触发并被发送到当前焦点控件。有三种不同的键盘事件:

一个常用的应用需求是,当Esc键被按下时,退出整个应用。

wxpython安装过程(wxPython-系统常用事件)(6)

图5:wx.KeyEvent类继承关系

#键盘事件(wx.FocusEvent) import wx class SampleKeyEvent(wx.Frame): def __init__(self, *args, **kw): super(SampleKeyEvent, self).__init__(*args, **kw) self.InitUi() def InitUi(self): panel = wx.Panel(self) panel.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) panel.SetFocus() self.SetSize(400, 280) self.SetTitle("实战wxPython: 键盘事件") self.Centre() def OnKeyDown(self, e): key = e.GetKeyCode() if key == wx.WXK_ESCAPE: ret = wx.MessageBox("确定要退出应用?", "问题", wx.YES_NO|wx.NO_DEFAULT, self) if ret == wx.YES: self.Close() def main(): app = wx.App() sample = SampleKeyEvent(None) sample.Show() app.MainLoop() if __name__ == "__main__": main()

在这个例子中,我们处理了Esc键按下事件,当按下Esc键时,会弹出一个对话框,询问是否关闭应用。

panel.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)

上面代码将EVT_KEY_DOWN事件绑定至self.OnKeyDown()方法。在OnKeyDown方法中,通过

key = e.GetKeyCode()

获得按键值,然后检查按键值是否为wx.WXK_EACAPE, 如果是,则弹出对话框,询问是否退出应用。

wxpython安装过程(wxPython-系统常用事件)(7)

图6:KeyEvent演示

四、鼠标事件(wx.KeyEvent)

鼠标事件类包含关于鼠标生成的事件的信息:它们包括鼠标按钮按下并释放事件和鼠标移动事件。

所有涉及按钮的鼠标事件都使用MOUSE_BTN_LEFT作为鼠标左键,MOUSE_BTN_MIDDLE作为中间键,MOUSE_BTN_RIGHT作为右边键。如果系统支持更多按钮,还可以生成MOUSE_BTN_AUX1和MOUSE_BTN_AUX2事件。注意,并不是所有的鼠标都有一个中间按钮,所以便携式应用程序应该避免依赖于它的事件(但是在Mac平台下,可以使用鼠标左键和控制键来模拟单击右键)。

注意:对于wxEVT_ENTER_WINDOW和wxEVT_LEAVE_WINDOW事件的目的,如果鼠标在窗口客户端区域中,而不在它的一个子窗口中,则认为鼠标在窗口内。换句话说,父窗口不仅在鼠标完全离开窗口时接收wxEVT_LEAVE_WINDOW事件,而且在鼠标进入其中一个子窗口时也接收wxEVT_LEAVE_WINDOW事件。

与鼠标事件相关的位置用生成事件窗口的窗口坐标表示,我们可以使用wx.Window.ClientToScreen将其转换为屏幕坐标,也可以调用wx.Window.ScreenToClient将其转换为另一个窗口的窗口坐标。

wxpython安装过程(wxPython-系统常用事件)(8)

图7:wx.MouseEvent类继承关系

#鼠标事件(wx.MouseEvent) import wx class SampleMouseEvent(wx.Frame): def __init__(self, *args, **kw): super(SampleMouseEvent, self).__init__(*args, **kw) self.info = "" self.Bind(wx.EVT_PAINT, self.OnPaint) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp) self.Bind(wx.EVT_MOTION, self.OnMouseMove) self.SetTitle("实战wxPython: 鼠标事件") self.SetSize(400, 280) self.Centre() def OnPaint(self, e): dc = wx.PaintDC(self) dc.DrawText(self.info, 20, 20) def OnLeftDown(self, e): self.info = "Mouse left button is pressed" self.Refresh(); def OnLeftUp(self, e): self.info = "Mouse left button is released" self.Refresh() def OnMouseMove(self, e): #如果按下左键并移动鼠标,则显示当前鼠标的坐标信息 if e.Dragging() and e.LeftIsDown(): x,y = e.GetPosition() self.info = "current pos: x=" str(x) ", y=" str(y) self.Refresh() def main(): app = wx.App() sample = SampleMouseEvent(None) sample.Show() app.MainLoop() if __name__ == "__main__": main()

上面的例子我们演示了鼠标左键按下,鼠标左键释放,以及鼠标移动的情况,当鼠标左键按下或者释放时,在窗口中输出相应的信息,如果鼠标左键按下且移动,则在窗口中显示鼠标的位置信息。

wxpython安装过程(wxPython-系统常用事件)(9)

图8:MouseEvent演示

五、本文知识点


前一篇:wxPython - 事件标识符

请关注,评论,收藏,点赞,和转发。

,