首页 > 解决方案 > 在 kivy 中不起作用的函数的动态绑定

问题描述

我想为一组小部件创建一个动态类,所以每当我将它们添加到我的主应用程序时,我只需要从某个地方引入更改(例如 python 文件、类等,这里我已经在显式列表中完成了它们),但是将小部件与响应事件的“on_text”等属性绑定并没有真正起作用,“text”、“hint_text”等其他属性工作得很好,但 on_text 并没有真正让步。我无法找出原因,因为我检查了函数传递的正确对象,下面是我的代码:

from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.properties import ObjectProperty



class Dynamic_TextInput(BoxLayout):
    def __init__(self,changes=None, **kwargs):
        super().__init__(**kwargs)
        self.widgets = {'Mylabel':self.ids.mylabel,
                        'Myinput': self.ids.mytext}
        self.Change(changes)


    def Change(self, changes=None, **kwargs):
        if changes: 
            for change in changes:
                curwidget = self.widgets[change[0]]
                cur_properties = change[1]
                for attr in cur_properties.keys():
                    if attr=='bind':
                        print("The cur properties are: ")
                        print(cur_properties[attr])
                        curwidget.bind(**(cur_properties[attr]))
                    else: 
                        setattr(curwidget, attr, cur_properties[attr])  



class mainwidget(BoxLayout):
    myobj1 = ObjectProperty()
    myobj2 = ObjectProperty() 
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.orientation='vertical'


        change1=[('Mylabel', {'text':'firstchange',
            'bind':{'on_text':lambda *_: print('something')}
            }),
                    ('Myinput', {'hint_text': 'Changed hint text'})
                ]

        self.add_widget(Dynamic_TextInput(changes=change1))
        self.add_widget(Dynamic_TextInput())


class MainApp(App):
    def build(self):
        return mainwidget()


if __name__ == '__main__':
    MainApp().run()    

并且,在 kivy 文件中:

#:kivy 1.10.0


<Dynamic_TextInput>:
    myobj1: mylabel
    myobj2: mytext
    orientation: 'horizontal'
    Label:
        id: mylabel
        text: 'testlable'
    TextInput:
        id: mytext
        hint_text: 'some test'   

原因是什么?我该如何解决?

标签: python-3.xkivy

解决方案


有两种方法可以绑定属性:

*.py

object.bind(property=callback)

*.kv

object:
    on_property: callback    

因此,在使用 python 进行连接的情况下,您不应该使用on_text, 但是text.

为了验证更改,不能从 GUI 编辑标签,所以我将使用TextInput写在Label

*.py

from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.properties import ObjectProperty


class Dynamic_TextInput(BoxLayout):
    def __init__(self,changes=None, **kwargs):
        super().__init__(**kwargs)
        self.widgets = {'Mylabel':self.ids.mylabel,
                        'Myinput': self.ids.mytext}
        self.Change(changes)


    def Change(self, changes=None, **kwargs):
        if changes: 
            for change in changes:
                curwidget = self.widgets[change[0]]
                cur_properties = change[1]
                for attr in cur_properties.keys():
                    if attr=='bind':
                        print("The cur properties are: ")
                        curwidget.bind(**(cur_properties[attr]))
                        print(cur_properties[attr])
                    else: 
                        setattr(curwidget, attr, cur_properties[attr])  


class mainwidget(BoxLayout):
    myobj1 = ObjectProperty()
    myobj2 = ObjectProperty() 
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.orientation='vertical'


        change1=[('Mylabel', {'text':'firstchange',
            'bind':{'text':lambda *_: print('something')}
            }),
                    ('Myinput', {'hint_text': 'Changed hint text'})
                ]

        self.add_widget(Dynamic_TextInput(changes=change1))
        self.add_widget(Dynamic_TextInput())


class MainApp(App):
    def build(self):
        return mainwidget()


if __name__ == '__main__':
    MainApp().run()    

*.kv

#:kivy 1.10.0


<Dynamic_TextInput>:
    myobj1: mylabel
    myobj2: mytext
    orientation: 'horizontal'
    Label:
        id: mylabel
        text: mytext.text # <----
    TextInput:
        id: mytext
        hint_text: 'some test'   

推荐阅读