为什么kivy中的'on_ <propname>'没有被调用?

时间:2016-05-15 11:46:35

标签: properties kivy

在kivy文档(1.9.0-dev)中,它说

  

观察使用'on_<propname>'如果您自己创建了课程,那么   可以使用“on_<propname>”回调:

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)

然后不调用on_a函数。我想如果我把on_作为一个函数名,那么我就不需要做bind()了。我想念一下吗?

=============================================== ==

聚苯乙烯。我在下面简化了我的代码。这是一个完整的可运行代码。

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

#: 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()

1 个答案:

答案 0 :(得分:1)

谢谢zeeMonkeez。

是。这正是问题所在。添加构造函数super(CourseCnDetailListView, self).__init__(**kwargs)后。它运作得很好。

当我改变结构时意外删除了它。非常感谢你。

同样很高兴知道它是EventDispatcher make <on_propname>的默认构造函数。