为什么不调用 kivy 中的“on_<propname>"? [英] Why ‘on_&lt;propname&gt;’ in kivy is not called?

查看:14
本文介绍了为什么不调用 kivy 中的“on_<propname>"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆