wxpython - 在外部文件中绑定事件

时间:2011-05-12 06:58:39

标签: python wxpython

我正在尝试绑定GUI文件中的事件以使用来自另一个文件的代码(实际上是“前端”和“后端”)。我可以让后端和前端在同一个文件中工作,但是当我尝试将它们移动到单独的文件中时,我有问题让后端看到前端的部件(标签,按钮等)。 / p>

予。 E.我需要后端代码来更改标签并进行数学等操作,并且需要影响GUI。

我提供了一个简单的程序版本。除了我尝试让后端看到GUI的各个部分时出现的错误,一切正常。

mainfile.py

#!/usr/bin/python
# -*- coding: utf-8 -*-

import wx

import label_changer

class foopanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent, id=wx.ID_ANY)

        box = wx.BoxSizer()
        btn = wx.Button(self,1,"Press")
        btn.Bind(wx.EVT_BUTTON,label_changer.change_label(self))
        box.Add(btn)

        self.lbl = wx.StaticText(self,1,"Foobar")
        box.Add(self.lbl)

        self.SetSizerAndFit(box)

class main_frame(wx.Frame):
    """Main Frame holding the main panel."""
    def __init__(self,*args,**kwargs):
        wx.Frame.__init__(self,*args,**kwargs)

        sizer = wx.BoxSizer()

        self.p = foopanel(self)

        sizer.Add(self.p,1)

        self.Show()

if __name__ == "__main__":
    app = wx.App(False)
    frame = main_frame(None,-1,)
    app.MainLoop()

label_changer.py

def change_label(self):
    self.p.lbl.SetLabel("barfoo")

我想要它做的就是更改GUI的标签,但使用外部文件。

我这样做主要是为了让我的代码保持独立,就像学习经验一样。

提前致谢!

3 个答案:

答案 0 :(得分:2)

一种解决方案是修改change_label以接受标识要更改的标签的参数。例如:

def change_label(event, label):
    label.SetLabel("barfoo")

然后,使用lambda创建一个在...中传递该参数的回调:

btn.Bind(wx.EVT_BUTTON, label_changer, 
    lambda event, label=self.p.lbl: label_changer.change_label(event, label))

确保在进行绑定之前定义self.lbl

有关将参数传递给回调的详情,请参阅Passing Arguments to Callbacks

上的WxPyWiki

答案 1 :(得分:1)

执行此操作的常用方法是MVC Pattern和pubsub。请参阅此Example

答案 2 :(得分:0)

btn.Bind(wx.EVT_BUTTON,label_changer.change_label(self))

需要

btn.Bind(wx.EVT_BUTTON,label_changer.change_label)

和这个

def change_label(self):
    self.p.lbl.SetLabel("barfoo")

需要

def change_label(event):
    panel = event.GetEventObject().GetParent()
    panel.lbl.SetLabel("barfoo")

为了澄清,您需要将对函数的引用传递给事件发生时要调用的Bind。 wx将始终将一个参数传递给这些函数 - 事件。您通常在回调中看到的self是它们被绑定方法的副产品。每个绑定方法(过度简化,在类中定义的函数)在被调用时隐式传递第一个参数,它是对类实例的引用。因此,您无法通过事件对象在“外部”函数中使用传统方式来访问此实例。

还有一件事,你不是真的以这种方式将gui与逻辑分开。这是因为逻辑(在这种情况下为label_changer)需要知道gui并直接操作它。有很多方法可以实现更强大的分离(st2053暗示其中一个)但是对于一个相对较小的程序,如果你现在不想要,你不需要打扰,只需将代码分成多个文件并专注于获取做的事情很好。您可以稍后担心架构。