为什么不调用 kivy 中的“on_<propname>"? [英] Why ‘on_<propname>’ in kivy is not called?
问题描述
在 kivy 文档 (1.9.0-dev) 中,它说
in the kivy document (1.9.0-dev), it says
使用‘on_<propname>
’观察如果你自己创建了这个类,你可以使用'on_<propname>
'回调:
Observe using ‘
on_<propname>
’ If you created the class yourself, you can use the ‘on_<propname>
’ callback:
class MyClass(EventDispatcher):
a = NumericProperty(1)
def on_a(self, instance, value):
print(’My property a changed to’, value)
我的代码是
class MyClass(EventDispatcher):
a = StringProperty('')
def __init__(self, **kwargs):
...
self.bind(a=self.on_a) <--- if I remove this
def on_a(self, instance, value):
print(’My property a changed to’, value)
这行得通.但是如果我删除 self.bind(a=self.on_a)
This works. But if I remove self.bind(a=self.on_a)
然后 on_a 函数没有被调用.我想如果我把 on_ 作为函数名,那么我不需要做 bind().我错过了什么吗?
Then on_a function is not called. I thought if I put on_ as a function name then I do not need to do bind(). Do I miss something?
==================================================
=================================================
附言.我在下面简化了我的代码.这是一个完整的可运行代码.
Ps. I simplified my code below. It is a full run-able code.
course_view.py:
course_view.py:
from kivy.app import App
from kivy.properties import StringProperty
from kivy.event import EventDispatcher
from kivy.uix.listview import ListView, ListItemButton
from kivy.adapters.dictadapter import DictAdapter
from kivy.uix.boxlayout import BoxLayout
from kivy.factory import Factory
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
from kivy.properties import ObjectProperty
from kivy.properties import StringProperty
class ChangeTest(App):
pass
class StartScreen(Screen):
pass
def load_view(self):
self.course_view_object = CourseCnDetailListView(view_box = self.ids.view_box)
self.clear_widgets()
self.add_widget(self.course_view_object.master_item_list)
class CourseCnDetailListView(EventDispatcher):
course_code = StringProperty('course_code_str')
def __init__(self, **kwargs):
self.view_box = kwargs.get('view_box', None)
self.course_data= {"1": {"course_code": "it123"},
"2": {"course_code": "it456"}
}
list_item_args_converter =
lambda row_index, rec: {'text': rec["course_code"],
'size_hint_y': None,
'height': 25}
dict_adapter = DictAdapter(sorted_keys=sorted(self.course_data.keys()),
data=self.course_data,
args_converter=list_item_args_converter,
selection_mode='single',
allow_empty_selection=False,
cls=ListItemButton)
self.master_item_list = ListView(adapter=dict_adapter,
size_hint=(.3, 1.0))
dict_adapter.bind(on_selection_change=self.course_changed)
#self.bind(course_code=self.on_course_code) <-- un-comment this will work
def on_course_code(self, instance, value):
print "on_course_code: update string value:", value
def redraw(self, *args):
pass
def course_changed(self, list_adapter, *args):
if len(list_adapter.selection) != 0:
selection = list_adapter.selection[0]
if type(selection) is str:
self.course_code = selection
else:
self.course_code = selection.text
self.redraw()
ChangeTest().run()
Factory.register('StartScreen', cls=StartScreen)
ChangeTest.kv
ChangeTest.kv
#: kivy 1.9
#: import ScreenManager kivy.uix.screenmanager.ScreenManager
#: import Screen kivy.uix.screenmanager.ScreenManager
ScreenManager:
id: screen_manager
StartScreen:
id: start_screen
name: 'StartScreen'
manager: screen_manager
<StartScreen>:
BoxLayout:
id: view_box
Button:
text: "load view"
on_release: root.load_view()
推荐答案
谢谢 zeeMonkeez.
Thank you zeeMonkeez.
是的.这正是问题所在.在我添加构造函数 super(CourseCnDetailListView, self).__init__(**kwargs)
之后.效果很好.
Yes. That is exactly the problem. After I add the constructor super(CourseCnDetailListView, self).__init__(**kwargs)
. It works perfectly.
当我改变结构时,它被意外删除了.非常感谢.
It was accidentally removed when I changed the structure. Thank you very much.
另外很高兴知道它是 EventDispatcher 的默认构造函数,使 <on_propname>
工作.
Also it is good to know that it is the default constructor of EventDispatcher make <on_propname>
work.
这篇关于为什么不调用 kivy 中的“on_<propname>"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!