事件──── 是每个 GUI 应用不可舍割的一部分,因为所有的 GUI 应用程序都是基于事件驱动的。从 GUI 程序启动开始,它就回应同户的不同类型的事件。除了用户,也有其它因素可以产生事件,例如:互联网连接,窗口管理器,定时器等等。所以,当我们调 MainLoop() 的时候,我们的程序就开始等待事件的产生,直至应用程序退出。

一个简单的例子

下面我们将以一个 move envet 事件为例子。当我们一个窗口到一个新的位置的时候 ,就会产生一个 move envet 事件,其类型是 wx.MoveEvent,对应的 Binder 是 wx.EVT_MOVE。

#!/usr/bin/python
# moveevent.py

import wx

class MoveEvent(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(250, 180))

wx.StaticText(self, -1, ‘x:’, (10,10))
        wx.StaticText(self, -1, ‘y:’, (10,30))
        self.st1 = wx.StaticText(self, -1, ”, (30, 10))
        self.st2 = wx.StaticText(self, -1, ”, (30, 30))

self.Bind(wx.EVT_MOVE, self.OnMove)

self.Centre()
        self.Show(True)

def OnMove(self, event):
        x, y = event.GetPosition()
        self.st1.SetLabel(str(x))
        self.st2.SetLabel(str(y))

app = wx.App()
MoveEvent(None, -1, ‘move event’)
app.MainLoop()

上面的例子将显示窗口的当前位置。

self.Bind(wx.EVT_MOVE, self.OnMove)

将 wx.EVT_MOVE 事件绑定到 OnMove() 方法上。

def OnMove(self, event):
     x, y = event.GetPosition()

参数 event 是指定事件类型的对象,在我们的例子中,它是 wx.MoveEvent 对象。wx.MoveEvent 是 wx.Frame 的 widget,我们可以调用 GetPosition() 来取得当前窗口的位置。

事件绑定

通过三步来进行事件的绑定:

  • 指定 event binder:wx.EVT_SIZE,wx.EVT_CLOSE 等等。
  • 创建事件处理函数。
  • 将事件绑定到事件函数上。

通过调用 Bind() 方法来绑定事件,下面是其参数:

Bind(event, handler, source=None, id=wx.ID_ANY, id2=wx.ID_ANY)
  • event 是 EVT_* 对象,指定事件的类型。
  • handler 事件的处理函数。
  • source 用于区分不同 widgets 的同一类型事件。
  • id :例如当你有多个按钮的时候,id 参数用于区分它们。
  • id2 :用于绑定多个连续的 ids 到同一 handler,例如:EVT_MENU_RANGE。

注意: Bind() 是定义于类 EvtHandler 中的方法,而 wx.Window 是它的子类。
如果想对事件进行解绑,可以使用 Unbind(),它跟 Bind() 有着相同的参数。

拦截事件

有时,我们需要停止处理某个事件,这就要用到方法 Veto()。

#!/usr/bin/python
# veto.py

import wx

class Veto(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(250, 200))

self.Bind(wx.EVT_CLOSE, self.OnClose)

self.Centre()
        self.Show(True)

def OnClose(self, event):

dial = wx.MessageDialog(None, ‘Are you sure to quit?’, ‘Question’,
            wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION)
        ret = dial.ShowModal()
        if ret == wx.ID_YES:
            self.Destroy()
        else:
            event.Veto()

app = wx.App()
Veto(None, -1, ‘Veto’)
app.MainLoop()

在上面的例子中,我们处理了一个 wx.CloseEvent 事件────当窗口关闭时就会触发。在某些应用程序里,我们希望阻止关闭窗口。

dial = wx.MessageDialog(None, ‘Are you sure to quit?’, ‘Question’,
     wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION)
 ret = dial.ShowModal()

当触发关闭事件,我们将显示一个消息对话框。

if ret == wx.ID_YES:
     self.Destroy()
 else:
     event.Veto()

根据返回值,我们决定关闭窗口还是拦截关闭事件。注意:我们必须通过调用 Destory() 方法来关闭窗口,来停止最终的事件循环。

事件传送(Event propagation)

事件大体可以分两类:普通事件(Basic events)和命令事件(Command events),它们的区别在于传送的不同。事件传送是指事件从一个子 widgets 传递到父 widgets 或者更上一级的父 widgets。普通事件没有传送,而命令事件则有。举一个例子,wx.CloseEvent 是一个普通事件,它不会将关闭事件传递到父一级的 widgets。

普通,当一个事件处理器(Event handler)捕获一个事件,它会阻止这个事件继续向上一级传送。要想继续事件的传递,必须使用 Skip() 方法。

#!/usr/bin/python
# propagate.py

import wx

class MyPanel(wx.Panel):
    def __init__(self, parent, id):
        wx.Panel.__init__(self, parent, id)

self.Bind(wx.EVT_BUTTON, self.OnClicked)

def OnClicked(self, event):
        print ‘event reached panel class’
        event.Skip()

class MyButton(wx.Button):
    def __init__(self, parent, id, label, pos):
        wx.Button.__init__(self, parent, id, label, pos)

self.Bind(wx.EVT_BUTTON, self.OnClicked)

def OnClicked(self, event):
        print ‘event reached button class’
        event.Skip()

class Propagate(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(250, 150))

panel = MyPanel(self, -1)

MyButton(panel, -1, ‘Ok’, (15, 15))

self.Bind(wx.EVT_BUTTON, self.OnClicked)

self.Centre()
        self.Show(True)

def OnClicked(self, event):
        print ‘event reached frame class’
        event.Skip()

app = wx.App()
Propagate(None, -1, ‘Propagate’)
app.MainLoop()

在上面的例子中,我们在窗口上放置一个面板,在面板上又放置一个按钮。

event reached button class
 event reached panel class
 event reached frame class

当我们单击按钮,将会显示上面的内容。这是因为单击事件从按钮一直传递到面板和窗口。有兴趣的话,可以注释掉 Skip(),看看有什么不同的事情发生。

窗口识别码(Window identifiers)

窗口识别码是一个唯一的整数,用于在事件系统中对不同窗口的识别。可以通过3个方法创建窗口 id’s:

  • 由系统自动创建 id
  • 使用标准的识别码
  • 用户自己创建 id

每一个 widget 都有一个 id 参数,它是事件系统中的唯一识别码。

wx.Button(parent, -1)
 wx.Button(parent, wx.ID_ANY)

如果我们设置 id 参数为 -1 或者 wx.ID_ANY,表示让 wxPython 自动创建 id。自动创建的 id’s 总是负数来的,而用户定义的 id’s 必须总是正数。

#!/usr/bin/python
# automaticids.py

import wx

class AuIds(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(170, 100))

panel = wx.Panel(self, -1)
        exit = wx.Button(panel, -1, ‘Exit’, (10, 10))

self.Bind(wx.EVT_BUTTON,  self.OnExit, id=exit.GetId())

self.Centre()
        self.Show(True)

def OnExit(self, event):
        self.Close()

app = wx.App()
AuIds(None, -1, ”)
app.MainLoop()

在上面的例子中,我们不用关心实际的 id 值。

self.Bind(wx.EVT_BUTTON,  self.OnExit, id=exit.GetId())

通过调用 GetId() 方法取得自动创建的 id 的值。

标准识别码(Standar identifiers)也可以随时使用,而且在某此平台上,它提供了一些标准图标和行为。

#!/usr/bin/python
# identifiers.py

import wx

class Identifiers(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(200, 150))

panel = wx.Panel(self, -1)
        grid = wx.GridSizer(3, 2)

grid.AddMany([(wx.Button(panel, wx.ID_CANCEL), 0, wx.TOP | wx.LEFT, 9),
            (wx.Button(panel, wx.ID_DELETE), 0, wx.TOP, 9),
            (wx.Button(panel, wx.ID_SAVE), 0, wx.LEFT, 9),
            (wx.Button(panel, wx.ID_EXIT)),
            (wx.Button(panel, wx.ID_STOP), 0, wx.LEFT, 9),
            (wx.Button(panel, wx.ID_NEW))])

self.Bind(wx.EVT_BUTTON, self.OnQuit, id=wx.ID_EXIT)

panel.SetSizer(grid)
        self.Centre()
        self.Show(True)

def OnQuit(self, event):
        self.Close()

app = wx.App()
Identifiers(None, -1, ”)
app.MainLoop()

Miscellaneous events

Focus 事件

所谓焦点(Focus)是程序中指当前被选择的 widget。当一个文本 widget 获得焦点时,我们可以从键盘输入字符或者从粘贴板中粘贴文本。

有2种 Focus 事件 Handlers:wx.EVT_SET_FOCUS,当一个 widget 获得焦点的时候来触发;wx.EVT_KILL_FOCUS,当 widget 失去焦点的时候会触发。焦点的改变可能通过鼠标的单击或者键盘按键,通常是 Tab/Shit+Tab。

#!/usr/bin/python
# focusevent.py

import wx

class MyWindow(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent, -1)

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, event):
        dc = wx.PaintDC(self)

dc.SetPen(wx.Pen(self.color))
        x, y = self.GetSize()
        dc.DrawRectangle(0, 0, x, y)

def OnSize(self, event):
        self.Refresh()

def OnSetFocus(self, event):
        self.color = ‘#0099f7′
        self.Refresh()

def OnKillFocus(self, event):
        self.color = ‘#b3b3b3′
        self.Refresh()

class FocusEvent(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(350, 250))

grid = wx.GridSizer(2, 2, 10, 10)
        grid.AddMany([(MyWindow(self), 1, wx.EXPAND|wx.TOP|wx.LEFT,9),
            (MyWindow(self), 1, wx.EXPAND|wx.TOP|wx.RIGHT, 9), 
            (MyWindow(self), 1, wx.EXPAND|wx.BOTTOM|wx.LEFT, 9), 
            (MyWindow(self), 1, wx.EXPAND|wx.BOTTOM|wx.RIGHT, 9)])

self.SetSizer(grid)
        self.Centre()
        self.Show(True)

app = wx.App()
FocusEvent(None, -1, ‘focus event’)
app.MainLoop()

ScrollEvent

当我们按下内建生成的滚动条的时候(使用 SetScrollbar() 来激活内建的滚动条),会触发  wx.ScrollWinEvent 事件。对于非内建的滚动条,其事件类型为 wx.ScrollEvent。

#!/usr/bin/python
# myscrollwinevent.py

import wx

class ScrollWinEvent(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title)
        panel = wx.Panel(self, -1)
        self.st = wx.StaticText(panel, -1, ’0′, (30,0))
        panel.Bind(wx.EVT_SCROLLWIN, self.OnScroll)
        panel.SetScrollbar(wx.VERTICAL, 0, 6, 50);
        self.Centre()
        self.Show(True)

def OnScroll(self, evt):
        y = evt.GetPosition()
        self.st.SetLabel(str(y))

app = wx.App()
ScrollWinEvent(None, -1, ‘scrollwinevent.py’)
app.MainLoop()

SizeEvent

当我们改变窗口大小的时候,会触发 wx.SizeEvent 事件。

#!/usr/bin/python
# sizeevent.py

import wx

class SizeEvent(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title)

self.Bind(wx.EVT_SIZE, self.OnSize)
        self.Centre()
        self.Show(True)

def OnSize(self, event):
        self.SetTitle(str(event.GetSize()))

app = wx.App()
SizeEvent(None, 1, ‘sizeevent.py’)
app.MainLoop()

在上面的例子中,我们在标题栏上显示窗口的大小。

self.SetTitle(str(event.GetSize()))

通过调用事件对象的 GetSize() 方法取得当前窗口的大小。

PaintEvent

当一个窗口被重画的时候,会触发 PaintEvent 事件。当窗口大小被改变或者最大化窗口,又或者通过编程,都可以令到窗口重画。例如,我们调用 SetLabel() 来改变 wx.StaticText。注意,最小化窗口的时候,不会触发 PaintEvent 事件。

#!/usr/bin/python
# paintevent.py

import wx

class PaintEvent(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title)

self.count = 0
        self.Bind(wx.EVT_PAINT, self.OnPaint)
        self.Centre()
        self.Show(True)

def OnPaint(self, event):
        self.count = self.count + 1
        print self.count

app = wx.App()
PaintEvent(None, -1, ‘paintevent.py’)
app.MainLoop()

KeyEvent

当我们通过键盘按键时,会触发 wx.KeyEvent 事件。事件会传递到当前获得焦点的 widget。 wx.KeyEvent 事件有3种 hanlders:

  • wx.EVT_KEY_DOWN
  • wx.EVT_KEY_UP
  • wx.EVT_CHAR

在下面的例子中,当按下 Esc 键时会关闭应用程序。

#!/usr/bin/python
# keyevent.py

import wx

class KeyEvent(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title)

panel = wx.Panel(self, -1)
        panel.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
        panel.SetFocus()

self.Centre()
        self.Show(True)

def OnKeyDown(self, event):
        keycode = event.GetKeyCode()
        if keycode == wx.WXK_ESCAPE:
            ret  = wx.MessageBox(‘Are you sure to quit?’, ‘Question’, 
        wx.YES_NO | wx.NO_DEFAULT, self)
            if ret == wx.YES:
                self.Close()
        event.Skip()

app = wx.App()
KeyEvent(None, -1, ‘keyevent.py’)
app.MainLoop()

About these ads

转载于:https://www.cnblogs.com/springbarley/p/3368718.html

wxPython:事件相关推荐

  1. 使用WxPython进行Win32下Python编程

    最近在研究wxpython,需要在win32下编程. 1 另一种可供Python使用的GUI工具包叫做wxPython.目前这个工具对于Python环境来说还是陌生的,但正在Python开发者中间快速 ...

  2. 读书笔记-《wxPython in Action》一

    这本书讲的如何应用wxPhython模块.这个模块是python中比较有名的GUI模块. 一,欢迎来到wxPhython 要想用好这个模块就要明白这个模块核心是一个wx.App的类,一个是wx.Fra ...

  3. wxpython 事件驱动

    事件处理是wxPython程序工作的基本机制.主要执行事件处理的工作称为事件驱动.在这章 中我们将讨论什么是事件驱动应用程序,它与传统的应用程序有什么不同.我们将对在GUI编程中所使用的概念和术语提供 ...

  4. wxpython应用程序对象与顶级窗口_wxPython学习笔记(二)

    如何创建和使用一个应用程序对象? 任何wxPython应用程序都需要一个应用程序对象.这个应用程序对象必须是类wx.App或其定制的子类的一个实例.应用程序对象的主要目的是管理幕后的主事件循环. 父类 ...

  5. wxPython界面开发总结

    1.GUI编程概述 Python需要界面么? 大多数情况下是不需要的,但是如果要给非开发者用,那么有个界面还是必要的.只需要掌握一种基本的界面开发方法,就能应付大多数情况. wxPython学习目标 ...

  6. wxpython初学者(四)之 事件驱动

    事件处理是wxPython程序工作的基本机制.主要执行事件处理的工作称为事件驱动.在这章 中我们将讨论什么是事件驱动应用程序,它与传统的应用程序有什么不同.我们将对在GUI编程中所使用的概念和术语提供 ...

  7. 全网最全面的python的讲解,讲的无可挑剔《记得收藏》

    全网最全面的python的讲解,讲的无可挑剔<记得收藏> 目录 1.简介 Pyhon中如何文件拷贝 Python数学库及其应用 Python异常处理机制 ETC turtle库的常用指令 ...

  8. My Python Summary

    Python的反射机制 简单的说通过dir(classname)可以获取类的方法及属性等,而通过globals()可以得到py文件中类Map,可以通过globals()[key]的方式创建对象,下所示 ...

  9. JavaScrpit 犀牛书第七版笔记

    JavaScrpit 犀牛书第七版笔记 挖个坑吧,JavaScript 犀牛书英文的第七版(JavaScript: The Definitive Guide, 7th Edition)其实在去年(20 ...

最新文章

  1. 比特币现金众筹应用Lighthouse正式上线
  2. 为什么我们要放弃win10 去使用deepinv20和ous呢
  3. 037_CSS媒介类型
  4. 配置MongoDB复制集
  5. NB-IoT与LoraWan技术分析与前景展望
  6. atitit.spring hibernate的事务机制 spring不能保存对象的解决
  7. nodejs gulp less编辑
  8. mysql 经典错误解决方案 :Incorrect string value ‘xE6x95x85xE4xBAx8B...‘ for column
  9. 怎样把计算机设置到小米手机桌面上,小米自由桌面如何设置和使用【图文教程】...
  10. Android 系统简单介绍
  11. 腾讯qq空间GET登陆JS分析
  12. 为什么说华为云WeLink是“最硬核”的协同办公工具?
  13. MySQL查询语句练习题(面试时可能会遇到哦!)
  14. Person Re-Identification(ReID行人重识别)
  15. 【vsftpd】Ubuntu下搭建FTP服务器
  16. JS中常见的 “Uncaught TypeError: XXXX is not a function” 错误解析
  17. 化工单元操作概念汇总
  18. 北大火星人科技创新为国家
  19. PCB 覆铜走线载流能力
  20. requests用法之爬取豆瓣排行

热门文章

  1. pythonista安卓版下载-pythonista 3ios
  2. Sequelize框架
  3. UVa910 TV game
  4. sed、cut和awk命令的使用
  5. 题目1128:求平均年龄
  6. Git:与GitHub搭配及SSH登录
  7. Redis 学习资料整理
  8. JQuery实现Ajax跨域访问--Jsonp原理
  9. phonegap一些事件
  10. 免费猪八戒网站软件任务小助手--小八戒更新版本1.5