所以,我知道我可以毫无问题地做到这一点:
button = widget.libray.Button()
class X():
@button.on_click
def click(self, event):
...
没有问题。
......但这很令人生气,因为现在'按钮'超出了课堂范围;我希望这是一个阶级财产。如何为类成员使用@blah修饰语法?
我当然不能使用装饰器,如下所示:
class UiDemo(cocos.cocosnode.CocosNode):
def on_enter(self):
self.b = Button(text='Hello World')
self.bt = b.event(self.bt) # <--- !!! Instead of decorator!
vbox = VBox(elements=[self.b])
self.dialog = Dialog(title='My Dialog', x=100, y=100, content=vbox, width=200, height=100)
cocos.director.director.window.push_handlers(self.dialog)
# @self.b.event doesn't work here, obviously.
def bt(self, button):
print('Button pressed: %s' % button)
def on_exit(self):
cocos.director.director.window.remove_handlers(self.dialog)
def draw(self):
self.dialog.on_draw()
class Client:
def run(self):
cocos.director.director.init()
test = UiDemo()
main_scene = cocos.scene.Scene(test)
cocos.director.director.run (main_scene)
我的意思是,我看到了问题;这个方法是在类定义时定义的(我猜),所以即使你在 init ()步骤中创建了widget,它也不存在于类定义的位置被解析,因此当时它不能用作装饰器。
我想知道的是,有什么方法可以解决这个问题吗?
肯定有很多情况你希望你的decorator属性引用附加到类的东西的实例?
(正如你从我上面的例子中看到的,这个不是只是一个“假设”情况;这是本周第二次我最终使用了详细的self.func = self.instance.dec(self.func)表单来执行此操作)
有什么建议吗?
(......显然,除了使用不这样做的库,因为它是愚蠢的;这不是真正的解决方案。:P)
答案 0 :(得分:3)
您可以将按钮设为类属性:
class X():
button = widget.libray.Button()
@button.on_click
def click(self, event):
# blah
如果您尝试连接多个X实例(因为它们将共享相同的按钮),这当然会导致问题,但如果您已全局定义button
,则这已成为问题。
您已准确诊断出问题:装饰发生在类定义时,但您希望方法与实例关联。最终,试图用这些技巧强迫它可能会让人感到困惑。您正在创建的按钮实例在概念上与X的实例相关联,而不是类本身。你可以合理地创建一个你打算多次实例化的GUI类(对于某些特定样式的小部件,或者其他什么),在这种情况下你必须放弃这些技巧,因为你真的需要在你希望绑定事件的时间。
如果你真的想,你可以设计一个更精细的方案来处理这个问题。例如,您可以使用@onclick('button')
之类的装饰器将名称button
存储为方法对象的属性。然后,您可以在__init__
中使用代码来迭代对象的方法,并将它们绑定到GUI小部件上具有相应名称的事件。 (也就是说,您创建一个按钮并将其存储为self.button
,然后__init__
将此属性的名称与传递给装饰器的名称相关联,并绑定事件。)
然而,做一件显而易见的事情可能更简单:不要尝试使用装饰器来处理类级别的特定于实例的行为。只需绑定方法代码中的事件,如第二个示例所示。
答案 1 :(得分:1)
在我看来,由于你想要装饰而没有必要,所以出现了混乱。你真正需要做的是注册一个回调。除了注册之外,还没有一点装饰回调。
将按钮作为成员,就像您已经拥有的那样,并将回调注册到它。
def on_enter(self):
self.b = Button(text='Hello World')
b.event(self.bt) # register, don't decorate
此外,您无法使用装饰器(除非创建全局Button
),因为装饰是在定义类时完成的,Button
member只在创建一个对象时被实例化,因此你不能在那时注册一个回调。