AttributeError: 'Button' object has no attribute 'update_label'.

旧城冷巷雨未停 提交于 2019-12-13 02:57:36

问题


I am stuck with my code, could you please help? After I added on_press to my kv file and describe function update_label, I got error:

AttributeError: 'Button' object has no attribute 'update_label'. 

Even if i change description of my function with simple print() function it doesn't works. Thanks in advance!

from kivy.app import App    
from kivy.uix.boxlayout import BoxLayout    
from kivy.lang import Builder    
from kivy.uix.button import Button    
from kivy.uix.label import Label    
from kivy.uix.stacklayout import StackLayout    
from kivy.uix.textinput import TextInput


Builder.load_file('spain2.kv')

class Box2(BoxLayout):
    pass

class Box1(StackLayout):
    pass


class Ex42App(App):
    def update_label(self):    
        if self.l1.text == 'amar':    
            self.l2.text = "Translate: to love"    
        else:    
            self.l2.text = "Infinitive not founded"

    def build(self):    
        return Box2()


if __name__=='__main__':

    Ex42App().run()

spain2.kv:

<Box2>:
    orientation: 'vertical'
    Box1:
        orientation: 'lr-tb'
        size_hint: 1, .1
        Label:
            id: l1
            text: 'Insert Infinitive'
            size_hint: None, None
            size: 150, 30
        TextInput:
            size_hint: None, None
            size: 300, 30
        Button:
            text: 'Find'
            size_hint: None, None
            size: 150, 30
            on_press: self.update_label

    Label:
        id: l2
        text: 'some data'
        size_hint: None, .9

回答1:


It seems that he does not know the meaning of self, root and app inside a .kv, for this case consider the following code:

<A>:
    property_a: self.a
    property_a1: root.a1
    B:
        property_b: self.b
        property_c1: root.b1
        C:
            property_c: self.c
            property_c1: root.c1

As the language .kv is observed, it is declarative and there is a tree of hierarchy.

In this case the root refers to the first element: <A>.

Instead the self refers to an element within the tree, in the case of self.a refers to the property a belongs to A, in the case of self.c refers to the property c belongs to C.

And in the case of app refers refers to the object that belongs to a class that inherits from App, and this object is unique, in your case app refers to the object Ex42App() that inherits from Ex42App.

So root and self is relative to a hierarchy tree, for example we can place a more complex structure:

<A>:
    B:
        some_property1: self.a # self is B
        some_property2: root.a # root is A

<Y>:
    Z:
        some_property1: self.a # self is Z
        some_property2: root.a # root is Y

With the above we analyze your case, according to what your code says update_label belongs to the Button but that is not correct, it belongs to App so you must use app, on the other hand update_label is a function so you must invoke it using ().

On the other hand in the code .py point out that l1 and l2 belongs to App but this does not belong to App but to Box2, but l1 and l2 is only visible inside Box2, so that it can be used outside of Box you must expose them as properties, and finally Box2 is the widget that returns build() and that element is accessed through self.root.

Considering the above, the solution is:

*.py

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder
from kivy.uix.stacklayout import StackLayout


Builder.load_file('spain2.kv')

class Box2(BoxLayout):
    pass

class Box1(StackLayout):
    pass


class Ex42App(App):
    def update_label(self):
        if self.root.l1.text == 'amar': # <--
            self.root.l2.text = "Translate: to love" # <--
        else:
            self.root.l2.text = "Infinitive not founded" # <--

    def build(self):
        return Box2()


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

*.kv

<Box2>:
    l1: l1 # <--
    l2: l2 # <--
    orientation: 'vertical'
    Box1:
        orientation: 'lr-tb'
        size_hint: 1, .1
        Label:
            id: l1
            text: 'Insert Infinitive'
            size_hint: None, None
            size: 150, 30
        TextInput:
            size_hint: None, None
            size: 300, 30
        Button:
            text: 'Find'
            size_hint: None, None
            size: 150, 30
            on_press: app.update_label() # <--

    Label:
        id: l2
        text: 'some data'
        size_hint: None, .9  


来源:https://stackoverflow.com/questions/53113040/attributeerror-button-object-has-no-attribute-update-label

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!