wxPython事件

事件是每一个GUI应用程序的组成部分。所有的GUI应用程序是事件驱动的。应用程序反应,以产生不同的事件,在其生命周期类型。事件的产生主要是由应用程序的用户。但它们可以产生,以及通过其他手段。例如互联网连接,窗口管理器,定时器。所以,当我们调用mainloop()方法,等待我们的应用程序产生事件。 mainloop()方法结束时退出应用程序。

定义

事件是一个从底层框架,通常的GUI工具包的应用程序级信息的一块。事件循环是一种编程构造和调度事件或程序中的消息等待。事件循环反复查找进程的事件。调度程序是一个过程,映射事件到事件处理程序。事件处理程序,对事件作出反应的方法。

事件对象是与事件相关联的对象。它通常是一个窗口。事件类型是一个已产生的独特的事件。事件绑定是一个对象,结合事件处理程序的事件类型。

一个简单的例子

这个例子里面讨论move事件。类型是wx.Movie的事件。此事件绑定是wx.EVT_MOTION。

[python] view plain copy
  1. ''''' 
  2. Created on 2012-7-5 
  3.  
  4. @author: Administrator 
  5. '''  
  6. import wx  
  7. import wx  
  8. class Example(wx.Frame):  
  9.     def __init__(self,parent,title):  
  10.         super(Example,self).__init__(parent,title=title,size=(500,300))  
  11.         self.InitUI()  
  12.         self.Centre()  
  13.         self.Show()  
  14.     def InitUI(self):  
  15.         wx.StaticText(self,label='x:',pos=(10,10))  
  16.         wx.StaticText(self,label='y:',pos=(10,30))  
  17.           
  18.         self.st1 = wx.StaticText(self,label='',pos=(30,10))  
  19.         self.st2 = wx.StaticText(self,label='',pos=(30,30))  
  20.           
  21.         self.Bind(wx.EVT_MOVE, self.OnMove)  
  22.           
  23.         self.SetSize((250180))  
  24.         self.SetTitle('Move event')  
  25.         self.Centre()  
  26.         self.Show(True)    
  27.     def OnMove(self,e):  
  28.         x,y = e.GetPosition()  
  29.   
  30.         self.st1.SetLabel(str(x))  
  31.         self.st2.SetLabel(str(y))  
  32.           
  33. if __name__ == '__main__':  
  34.     app = wx.App()  
  35.     Example(None,title="gotoclass")  
  36.     app.MainLoop()  


这个例子显示了当前位置的窗口,拖动窗口移动试试。

[python] view plain copy
  1. self.Bind(wx.EVT_MOVE, self.OnMove)  

这里我们将wx.EVT_MOVE事件绑定到OnMove方法上。
[python] view plain copy
  1. def OnMove(self, e):  
  2.       
  3.     x, y = e.GetPosition()  
  4.     self.st1.SetLabel(str(x))  
  5.     self.st2.SetLabel(str(y))  

在OnMove()方法的事件参数是一个对象,具体到一个特定的事件类型。在我们的例子,它是一个wx.MoveEvent类的实例。这个对象包含有关事件的信息。例如事件对象或窗口的位置。在我们的例子中,事件对象是wx.Frame的部件。我们用GetPosition()方法调用当前的位置。



事件绑定

在wxPython中,绑定是件很容易的事情,分三个步骤:

1.定义绑定的名字:wx.EVT_SIZE, wx.EVT_CLOSE等等。

2.创建事件处理,也就是方法。

3.绑定事件与方法。

[python] view plain copy
  1. Bind(event, handler, source=None, id=wx.ID_ANY, id2=wx.ID_ANY)  

1.event就是一种EVT_ *对象

2.handler就是方法。

3.source是我们要从不同的小部件中区分相同的事件类型。

4.当我们有多个按钮、菜单项等id用于区分它们。


否决事件
有时我们需要停止处理一个事件。要做到这一点,我们调用这个方法Veto()。
[python] view plain copy
  1. import wx  
  2. class Example(wx.Frame):  
  3.     def __init__(self,parent,title):  
  4.         super(Example,self).__init__(parent,title=title,size=(400,300))  
  5.         self.InitUI()  
  6.         self.Centre()  
  7.         self.Show()  
  8.     def InitUI(self):  
  9.         self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)  
  10.           
  11.     def OnCloseWindow(self,e):  
  12.         dial = wx.MessageDialog(None,"Are you Sure to Quit?","Question",  
  13.                                 wx.YES_NO|wx.NO_DEFAULT|wx.ICON_QUESTION)  
  14.         ret = dial.ShowModal()  
  15.           
  16.         if ret == wx.ID_YES:  
  17.             self.Destroy()  
  18.         else:  
  19.             e.Veto()  
  20.           
  21. if __name__ == '__main__':  
  22.     app = wx.App()  
  23.     Example(None,title="VetoMethod")  
  24.     app.MainLoop()  

当我们处理关闭窗口时,需要给用户一个提示,是否真的退出程序。Veto()方法可以返回正在处理的事件。


事件传播 

有两种类型的事件:基本事件和命令事件。他们有着不同的传播方法。基本事件不传播。命令事件可能传播。例如wx.CloseEvent是一个基本的事件。它并不适合这个事件传播到父窗口小部件。

默认情况下,事件,是在一个事件处理程序可以停止传播。如果要继续传播,我们必须调用Skip()方法。

[python] view plain copy
  1. import wx  
  2. class MyPanel(wx.Panel):  
  3.     def __init__(self,*args,**kw):  
  4.         super(MyPanel,self).__init__(*args,**kw)  
  5.         self.Bind(wx.EVT_BUTTON, self.OnButtonClicked)  
  6.     def OnButtonClicked(self,e):  
  7.         print "event reached panel class"  
  8.         e.Skip()  
  9.   
  10. class MyButton(wx.Button):  
  11.     def __init__(self,*args,**kw):  
  12.         super(MyButton,self).__init__(*args,**kw)  
  13.         self.Bind(wx.EVT_BUTTON, self.OnButtonClicked)  
  14.     def OnButtonClicked(self,e):  
  15.         print "event reached button class"  
  16.         e.Skip()  
  17.   
  18. class Example(wx.Frame):  
  19.     def __init__(self,*args,**kw):  
  20.         super(Example,self).__init__(*args,**kw)  
  21.         self.InitUI()  
  22.     def InitUI(self):  
  23.         mpnl = MyPanel(self)  
  24.         MyButton(mpnl,label='Ok',pos=(15,15))  
  25.         self.Bind(wx.EVT_BUTTON, self.OnButtonClicked)  
  26.           
  27.         self.SetTitle("Propagation")  
  28.         self.Centre()  
  29.         self.Show()  
  30.     def OnButtonClicked(self,e):  
  31.         print "event reached frame class"  
  32.         e.Skip()  
  33.   
  34. def main():  
  35.     ex = wx.App()  
  36.     Example(None)  
  37.     ex.MainLoop()  
  38. if __name__ == '__main__':  
  39.     main()  

这个例子中,frame里装着一个panel,一个button,当点button时它会把事件传播给panel,再传播给frame.

[python] view plain copy
  1. event reached button class  
  2. event reached panel class  
  3. event reached frame class  

如果你有兴趣,尝试省略一些Skip()方法,看看会发生什么。


组件的ID

识符是整数,惟一确定组件身份的事件系统。有三种方法可以创建的窗口id。

1.让系统自动创建。

2.使用标准ID

3.自己创建

[python] view plain copy
  1. wx.Button(parent, -1)  
  2. wx.Button(parent, wx.ID_ANY)  

上面两个-1与wx.ID_ANY都是让系统自动创建ID。但我们推荐使用标准ID或者自己创建ID。
[python] view plain copy
  1. import wx  
  2. class Example(wx.Frame):  
  3.     def __init__(self,*args,**kw):  
  4.         super(Example,self).__init__(*args,**kw)  
  5.         self.InitUI()  
  6.     def InitUI(self):  
  7.         panel = wx.Panel(self)  
  8.         grid = wx.GridSizer(3,2)  
  9.           
  10.         grid.AddMany([(wx.Button(panel,wx.ID_CANCEL),0,wx.TOP|wx.LEFT,9),  
  11.                       (wx.Button(panel, wx.ID_DELETE), 0, wx.TOP, 9),  
  12.                       (wx.Button(panel, wx.ID_SAVE), 0, wx.LEFT, 9),  
  13.                       (wx.Button(panel, wx.ID_EXIT)),  
  14.                       (wx.Button(panel, wx.ID_STOP), 0, wx.LEFT, 9),  
  15.                       (wx.Button(panel, wx.ID_NEW))])  
  16.           
  17.         self.Bind(wx.EVT_BUTTON, self.OnQuitApp,id=wx.ID_EXIT)  
  18.         panel.SetSizer(grid)  
  19.           
  20.         self.SetSize((220,180))  
  21.         self.SetTitle("window ID")  
  22.         self.Centre()  
  23.         self.Show()  
  24.     def OnQuitApp(self, event):  
  25.           
  26.         self.Close()  
  27.   
  28. def main():  
  29.     ex = wx.App()  
  30.     Example(None)  
  31.     ex.MainLoop()  
  32. if __name__ == '__main__':  
  33.     main()  

这里我们使用的都是标准ID,如果在Liux,这些按钮都带图标。
[python] view plain copy
  1. self.Bind(wx.EVT_BUTTON, self.OnQuitApp, id=wx.ID_EXIT)  
指定ID后,像这个id=wx.ID_EXIT。就可以处理它的事件了。



创建自己的ID

让我们来看看自己如何创建ID:

[python] view plain copy
  1. ''''' 
  2. Created on 2012-7-5 
  3.  
  4. @author: Administrator 
  5. '''  
  6. import wx  
  7.   
  8. ID_MENU_NEW = wx.NewId()  
  9. ID_MENU_OPEN = wx.NewId()  
  10. ID_MENU_SAVE = wx.NewId()  
  11.   
  12. class Example(wx.Frame):  
  13.     def __init__(self,*args,**kw):  
  14.         super(Example,self).__init__(*args,**kw)  
  15.         self.InitUI()  
  16.     def InitUI(self):  
  17.         self.CreateStatusBar()  
  18.         self.CreateMenuBar()  
  19.           
  20.         self.SetSize((250180))  
  21.         self.SetTitle('My Own ID')  
  22.         self.Centre()  
  23.         self.Show(True)    
  24.     def CreateMenuBar(self):  
  25.         mb = wx.MenuBar()  
  26.         fMenu = wx.Menu()  
  27.         fMenu.Append(ID_MENU_NEW,'New')  
  28.         fMenu.Append(ID_MENU_OPEN, 'Open')  
  29.         fMenu.Append(ID_MENU_SAVE, 'Save')  
  30.           
  31.         mb.Append(fMenu,'&File')  
  32.         self.SetMenuBar(mb)  
  33.           
  34.         self.Bind(wx.EVT_MENU, self.DisplayMessage,id=ID_MENU_NEW)  
  35.         self.Bind(wx.EVT_MENU, self.DisplayMessage,id=ID_MENU_OPEN)  
  36.         self.Bind(wx.EVT_MENU, self.DisplayMessage,id=ID_MENU_SAVE)  
  37.     def DisplayMessage(self,e):  
  38.         sb = self.GetStatusBar()  
  39.         eid = e.GetId()  
  40.           
  41.         if eid == ID_MENU_NEW:  
  42.             msg = 'New Menu item selected'  
  43.         elif eid==ID_MENU_OPEN:  
  44.             msg = 'Open menu item selected'  
  45.         elif eid == ID_MENU_SAVE:  
  46.             msg = 'Save menu item selected'  
  47.           
  48.         sb.SetStatusText(msg)  
  49.           
  50. def main():  
  51.       
  52.     ex = wx.App()  
  53.     Example(None)  
  54.     ex.MainLoop()      
  55.   
  56.   
  57. if __name__ == '__main__':  
  58.     main()    

[python] view plain copy
  1. ID_MENU_NEW = wx.NewId()  
  2. ID_MENU_OPEN = wx.NewId()  
  3. ID_MENU_SAVE = wx.NewId()  

wx.NewId()方法可以帮你创建一个唯一的id号供你使用。


重绘事件

我们窗口变大变小时或当我们最大化时,就会产生一个重绘事件。

[python] view plain copy
  1. import wx  
  2. class Example(wx.Frame):  
  3.              
  4.     def __init__(self, *args, **kw):  
  5.         super(Example, self).__init__(*args, **kw)   
  6.           
  7.         self.InitUI()  
  8.                   
  9.     def InitUI(self):  
  10.         self.count = 0  
  11.         self.Bind(wx.EVT_PAINT, self.OnPaint)  
  12.         self.SetSize((250180))  
  13.         self.Centre()  
  14.         self.Show(True)    
  15.     def OnPaint(self,e):  
  16.         self.count += 1  
  17.         self.SetTitle(str(self.count))  
  18.           
  19. def main():  
  20.       
  21.     ex = wx.App()  
  22.     Example(None)  
  23.     ex.MainLoop()      
  24.   
  25.   
  26. if __name__ == '__main__':  
  27.     main()    

焦点事件:
[python] view plain copy
  1. ''''' 
  2. Created on 2012-7-5 
  3.  
  4. @author: Administrator 
  5. '''  
  6. import wx  
  7. class MyWindow(wx.Panel):  
  8.     def __init__(self,parent):  
  9.         super(MyWindow,self).__init__(parent)  
  10.         self.color = '#b3b3b3'  
  11.           
  12.         self.Bind(wx.EVT_PAINT, self.OnPaint)  
  13.         self.Bind(wx.EVT_SIZE, self.OnSize)  
  14.         self.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus)  
  15.         self.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus)  
  16.           
  17.     def OnPaint(self,e):  
  18.         dc = wx.PaintDC(self)  
  19.           
  20.         dc.SetPen(wx.Pen(self.color))  
  21.           
  22.         x,y = self.GetSize()  
  23.         dc.DrawRectangle(0,0,x,y)  
  24.     def OnSize(self,e):  
  25.         self.Refresh()  
  26.     def OnSetFocus(self,e):  
  27.         self.color = '#0099f7'  
  28.         self.Refresh()  
  29.     def OnKillFocus(self,e):  
  30.         self.color = '#b3b3b3'  
  31.         self.Refresh()  
  32. class Example(wx.Frame):  
  33.     def __init__(self,*args,**kw):  
  34.         super(Example,self).__init__(*args,**kw)  
  35.         self.InitUI()  
  36.     def InitUI(self):  
  37.         grid = wx.GridSizer(2,2,10,10)  
  38.           
  39.         grid.AddMany([(MyWindow(self),0,wx.EXPAND|wx.TOP|wx.LEFT,9),  
  40.                        (MyWindow(self), 0, wx.EXPAND|wx.TOP|wx.RIGHT, 9),   
  41.                        (MyWindow(self), 0, wx.EXPAND|wx.BOTTOM|wx.LEFT, 9),   
  42.                        (MyWindow(self), 0, wx.EXPAND|wx.BOTTOM|wx.RIGHT, 9)])  
  43.           
  44.         self.SetSizer(grid)  
  45.   
  46.         self.SetSize((350250))  
  47.         self.SetTitle('Focus event')  
  48.         self.Centre()  
  49.         self.Show(True)    
  50.           
  51. def main():  
  52.       
  53.     ex = wx.App()  
  54.     Example(None)  
  55.     ex.MainLoop()      
  56.   
  57.   
  58. if __name__ == '__main__':  
  59.     main()    
上面例子中,四个panel,最亮的那个panel就是焦点。


键盘事件

当你敲击键盘时,键盘事件就产生了。它针对的就是当前获得焦点的控件。有三种不同的处理方法:

wx.EVT_KEY_DOWN
wx.EVT_KEY_UP
wx.EVT_CHAR

我们来看一下这个例子,当你按下Esc键时,来关闭程序。

[python] view plain copy
  1. import wx  
  2. class Example(wx.Frame):  
  3.              
  4.     def __init__(self, *args, **kw):  
  5.         super(Example, self).__init__(*args, **kw)   
  6.           
  7.         self.InitUI()  
  8.                   
  9.     def InitUI(self):  
  10.         pnl = wx.Panel(self)  
  11.         pnl.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)  
  12.         pnl.SetFocus()  
  13.           
  14.         self.SetSize((250180))  
  15.         self.SetTitle('Key event')  
  16.         self.Centre()  
  17.         self.Show(True)    
  18.           
  19.     def OnKeyDown(self,e):  
  20.         key = e.GetKeyCode()  
  21.           
  22.         if key == wx.WXK_ESCAPE:  
  23.             ret = wx.MessageBox("Are you sure to quit?","Question",  
  24.                                 wx.YES_NO|wx.NO_DEFAULT,self)  
  25.             if ret == wx.YES:  
  26.                 self.Close()  
  27.           
  28. def main():  
  29.       
  30.     ex = wx.App()  
  31.     Example(None)  
  32.     ex.MainLoop()      


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值