AttributeError: у объекта 'Button' нет атрибута 'update_label'. - PullRequest
0 голосов
/ 02 ноября 2018

Я застрял с моим кодом, не могли бы вы помочь? После того как я добавил on_press в свой файл kv и описал функцию update_label, я получил ошибку:

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

Даже если я изменил описание своей функции с помощью простой функции print (), она не работает. Заранее спасибо!

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 Ответ

0 голосов
/ 02 ноября 2018

Кажется, что он не знает значения self, root и app внутри .kv, для этого случая рассмотрим следующий код:

<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

Поскольку наблюдается язык .kv, он декларативный и существует дерево иерархии.

В этом случае root относится к первому элементу: <A>.

Вместо self относится к элементу в дереве, в случае self.a относится к свойству a принадлежит A, в случае self.c относится к свойству c принадлежит C.

А в случае приложения ссылка относится к объекту, который принадлежит классу, который наследуется от App, и этот объект является уникальным, в вашем случае приложение ссылается на объект Ex42App(), который наследуется от Ex42App.

Таким образом, root и self относятся к иерархическому дереву, например, мы можем разместить более сложную структуру:

<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

С учетом вышеизложенного мы анализируем ваш случай, согласно тому, что в вашем коде написано update_label относится к Button, но это не правильно, оно относится к App, поэтому вы должны использовать app, с другой стороны update_label - это функция, поэтому вы должны вызывать ее, используя ().

С другой стороны, в коде .py укажите, что l1 и l2 принадлежит App, но это относится не к App, а к Box2, но l1 и l2 виден только внутри Box2, так что его можно использовать за пределами Box, вы должны выставить их как свойства, и, наконец, Box2 - это виджет, который возвращает build() и доступ к этому элементу осуществляется через self.root.

Учитывая вышеизложенное, решение:

*. 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()

*. Киловольт

<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  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...