给wxPython事件处理函数传递参数

给wxPython事件处理函数传递参数

2014-04-30 07:47:08segmentfault-博客--点击数:39

最近捣鼓Python,也就自然捣鼓上了wxPython。我曾经用过Qt和Gtk+写GUI,但几乎所有的Python书都告诉我说最好用的是wxPython,我没有尝试PyQt和PyGtk就开始研究wxPython了。在Qt和Gtk+之间我更喜欢Qt,因为它跨平台做得很好,而且商业化也不错。但wxWidget给人的感觉就完全不同了。

如果说wxWidgets相对于Qt有什么优势的话,大概就只有体积较小了。从开发效率上看,如果不和Python组合真的比不上Qt;从商业支持上看wxWidgets根本没有。不过和Python组合之后,开发效率大大提高,虽然用来做很正式的商业软件并不合适,但写写小程序还是很方便的。

现在切入正题,wxWidgets是一个事件驱动的体系,对于触发的事件,需要给它挂上相应的事件处理函数。在Python中这个函数的形式是这样的:

wx.Frame.Bind(self, event, handler, source=None, id=-1, id2=-1)

在一般使用时,我们基本上只会给定event、handler和source,event是事件的名称,handler是处理函数,source是事件的发生者,比如一个Button1被单击而发生了EVT_BUTTON事件,如果我们用self.OnButton1()来处理,会这么写:

self.Bind(wx.EVT_BUTTON, self.OnButton1, self.Button1)

这里self是一个Frame(wxPython中的窗体这样的东西),而Button1是放在这个Frame下面的一个Button,self.OnButton1就是事件处理函数。而wxPython定死了事件处理函数的形式:

def handler(self,event):...

事件处理函数只能接受两个参数,一个还是self。至于event,一看就知道是那个发生的事件。但这样就有一个问题了:如果我想批量创建一些按钮或者菜单键(我想这种事情是很普遍的),并且希望用同一个函数来处理它们,这个函数该怎样辨别是哪个按钮触发的事件呢?显然我们希望能多传一些参数。Qt实现这一点很容易,但wxWidgets就显得很棘手了。

我并没有用C++写过wxWidgets的程序——确切地讲是复制过一个example的,但是不知道是我英语太拆还是真的没有,我没能在wxWidgets的入门指南中找到编译指令,最后没法编译它。因此我不知道这个限制是不是C++也有,但是Python可以通过lambda来解决这个问题。以下的例子我用的是菜单。

首先我们建一个OnMenusClick函数:

def OnMenusClick(self, event, mark):....

这个函数多接收一个mark,绑定的时候,就不是把OnMenusClick直接绑定上去,而是传递一个被lambda包装过的函数。下面这个例子就会建立一堆Menu的按键,并给他们编号,OnMenusClick就可以接收到它们的编号了:

menu=wx.Menu()for i in range(0,N):btn=menu.Append(wx.NewId(), str(i))self.Bind(wx.EVT_MENU, lambda evt, mark=i : self.OnMenusClick(evt,mark) ,btn )

完成了!是不是感觉有点magic?关键在于这句lambda

lambda evt, mark=i : self.OnMenusClick(evt,mark)

这句实际上产生了只接收evt一个参数的函数,并将其传递给了self.OnMenusClick,这样就能够实现给事件处理函数传递更多参数的目的了。

def OnClick(evt,agrv):
    print agrv
    print evt

def func(evt,function):
    function(evt)

func(2,lambda evt,argv=4:OnClick(evt,argv))
时间: 2024-10-11 01:20:59

给wxPython事件处理函数传递参数的相关文章

javascript如何给事件处理函数传递参数

javascript如何给事件处理函数传递参数:在应用中可能需要给注册的事件处理函数传递参数,但是会发现好像无法实现直接传递,下面就简单介绍一下如何给事件处理函数传递参数.先看一段代码实例: <!DOCTYPE html> <html> <head> <meta charset=" utf-8"> <meta name="author" content="http://www.softwhy.com/&

jquery事件处理函数的参数问题:event对象和自定义参数

jquery中如果需要给按钮绑定click事件处理函数,那么我们可以使用如下的代码: $("#button1").click( function() { alert("I was clicked."); } ); 一般我们都会按照上面的写法,注册事件处理函数,很少给处理函数传递参数.但是如果我们需要事件更详细的信息,比如事件发生时鼠标的位置等,那么我们就必须要使用事件对象了. 在IE和FF浏览器下,我们可以使用event对象拿到更多的信息.在jquery中拿到eve

js中函数传递参数,究竟是值传递还是引用传递?

记住真理: js函数传递参数,不管是简单数据类型,还是引用数据类型,都是值传递!! 下面是js红包书里面的例子: function setName(obj) { obj.name = "Nicholas"; obj = new Object(); obj.name = "Greg"; } var person = new Object(); setName(person); alert(person.name); // "Nicholas" 肯定

Delphi过程、函数传递参数的八种方式

Delphi过程函数传递参数的八种方式 Delphi过程.函数传递参数的八种方式,布布扣,bubuko.com

向线程函数传递参数

向线程函数传递参数在构造线程对象时即可完成.但是要记住,默认情况下是把参数拷贝到线程内部,即使在函数中使用的是引用.例如 void f(int i,std::string const &s); std::thread t(f,3,"hello");</span> 上面代码中,函数f的第二个参数是std::string,传递的是char const *会转换为string. 当使用指针指向自动变量时,要特别注意: <span style="font-s

js函数传递参数时,如果是路径类型的参数,里边包含:&#39;\&#39;字符报错

在函数中,传递的参数中有“\”字符,js会将它默认为转义字符串,如果没有出现与他匹配的转义字符串,就会缺失,例如: 将这样的一个字符串作为一个参数:C:\Program Files (x86)\MySQL\MySQL Server 5.7\data\ 传递到函数里边的值就会被默认转化为:C:Program Files (x86)MySQLMySQL Server 5.7data 如果要实现这个参数的精确传递,就需要将字符串进行处理,一般会有两种方式: ①:将字符串里边的 ‘\’ 字符替换成 ‘/

利用call与apply向函数传递参数

Js中函数对象都有call与apply两个方法属性,二者使用方法和功能一样,只是传递参数的格式不同,call逐个传递单个参数,apply一次性传递一个参数数组. 这两个方法可以改变函数的调用对象,并且向函数中传递参数.如: function send(str,speak){ speak.call(this,str); //send(~)==window.speak(str),这句话会立即调用执行此函数 } send("你好!",function(strword){ //这里以匿名函数对

c#教程之事件处理函数的参数

事件处理函数一般有两个参数,第一个参数(object sender)为产生该事件的对象的属性Name的值,例如上例单击标题为红色的按钮,第一个参数sender的值为button1.如上例标题为红色的按钮和标题为黑色的按钮使用同一个单击事件处理函数,其事件处理如下:private void button1_Click(object sender,System.EventArgs e){   if(sender==button1)label1.ForeColor=Color.Red;elselabe

函数传递参数的本质

研究实验5 问题引出:我们经过之前的研究已经知道了函数就是汇编中的子程序这样一个概念,那么但是函数的参数是如何传递呢,是汇编语言学习中参数传递的哪种方式呢? 问题研究: 图1-2  a.exe汇编代码 从图中的汇编代码我们可以清晰的发现,C语言中传递参数是通过栈来传递参数,这在之前汇编语言中是有介绍的.    图3  b.exe对应汇编代码 从图中的汇编代码可以看出,showchar 是根据第一个变量n值来确定要显示多少个字符的. 下面来研究这样一个问题:printf函数功能很强大,原因在于它对