我正在尝试绑定GUI文件中的事件以使用来自另一个文件的代码(实际上是“前端”和“后端”)。我可以让后端和前端在同一个文件中工作,但是当我尝试将它们移动到单独的文件中时,我有问题让后端看到前端的部件(标签,按钮等)。 / p>
予。 E.我需要后端代码来更改标签并进行数学等操作,并且需要影响GUI。
我提供了一个简单的程序版本。除了我尝试让后端看到GUI的各个部分时出现的错误,一切正常。
#!/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()
def change_label(self):
self.p.lbl.SetLabel("barfoo")
我想要它做的就是更改GUI的标签,但使用外部文件。
我这样做主要是为了让我的代码保持独立,就像学习经验一样。
提前致谢!
答案 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暗示其中一个)但是对于一个相对较小的程序,如果你现在不想要,你不需要打扰,只需将代码分成多个文件并专注于获取做的事情很好。您可以稍后担心架构。