kivy.event.EventDispatcher 类有一个名为 apply_property() 的方法它允许在运行时向类添加属性。 文档包含警告:
This method is not recommended for common usage because you should declare the properties in your class instead of using this method.
我不清楚为什么不鼓励这种用法,而首选在类中声明。谁能赐教一下?
请您参考如下方法:
apply_property() 用于将属性添加到单个类实例,但也有污染其他实例属性的副作用。考虑以下代码:
#!/usr/bin/kivy
import kivy
kivy.require('1.9.1')
from kivy.app import App
from kivy.lang import Builder
from kivy.properties import NumericProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
Builder.load_string('''
<MyButton>:
on_press: print('np' in self.properties())
''')
class MyButton(Button):
pass
class MainApp(App):
def build(self):
mb1 = MyButton(text="mb1")
mb2 = MyButton(text="mb2")
mb1.apply_property(np=NumericProperty(100))
layout = BoxLayout()
layout.add_widget(mb1)
layout.add_widget(mb2)
return layout
if __name__ == '__main__':
MainApp().run()
如您所见,即使我在 mb1 实例上使用了 apply_property,mb2 报告它也有这样的属性。这是因为属性被添加到类中,而不是实例中。但是,只有 mb1 具有实际值:
#!/usr/bin/kivy
import kivy
kivy.require('1.9.1')
from kivy.app import App
from kivy.lang import Builder
from kivy.properties import NumericProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
Builder.load_string('''
<MyButton>:
on_press: print(self.np)
''')
class MyButton(Button):
pass
class MainApp(App):
def build(self):
mb1 = MyButton(text="mb1")
mb2 = MyButton(text="mb2")
mb1.apply_property(np=NumericProperty(100))
layout = BoxLayout()
layout.add_widget(mb1)
layout.add_widget(mb2)
return layout
if __name__ == '__main__':
MainApp().run()
尝试从 mb2 实例获取 np 属性的值会产生一个 AttributeError。一个安全的选择:
#!/usr/bin/kivy
import kivy
kivy.require('1.9.1')
from kivy.app import App
from kivy.lang import Builder
from kivy.properties import NumericProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
Builder.load_string('''
<MyButton>:
on_press: print(self.np)
''')
class MyButton(Button):
np=NumericProperty(100)
class MainApp(App):
def build(self):
mb1 = MyButton(text="mb1")
mb2 = MyButton(text="mb2")
layout = BoxLayout()
layout.add_widget(mb1)
layout.add_widget(mb2)
return layout
if __name__ == '__main__':
MainApp().run()
来源:this issue .
