Kivy : AttributeError: 'Mylayout' object has no attribute 'hint'

Kivy : AttributeError: 'Mylayout' object has no attribute 'hint'

我是 python 的新手,我正在使用 Kivy 开发美国各州的抽认卡。抽认卡会随机排列美国各州的字母,用户需要输入答案。当用户不确定时,他可以点击获取提示按钮,抽认卡将显示一个字母,用户可以点击另一个字母直到显示所有字母。

us_state_flaskcard_3.py 文件

        from kivy.app import App
        from kivy.lang import Builder
        from kivy.uix.widget import Widget
        from kivy.core.window import Window
        from kivy.uix.button import Button
        
        from random import choice
        from random import shuffle
        
        Builder.load_file('us_state_flashcard.kv')
        
        Window.size = (350, 600)
        
        class MainApp(App):
            title='US State Flashcard'
            def build(self):
                Window.clearcolor = (255/255, 255/255, 0, 1) 
                return Mylayout()  
        
            def shuffler(self):
              
                self.root.ids.entry_answer.text = ''
                self.root.ids.answer_label.text = ''
                self.root.ids.hint_label.text = ''
        
                global hint_count
                hint_count = 0
        
                states= ['Washington', 'Oregon','California','Ohio','Nebraska',
                    'Wisconsin', 'Daleware','Arkansas','Louisiana','California',
                    'Michigan','Florida', 'Taxes','Kectucky','Alabama','Alaska',
                    'Arizona','Colorado','Connecticut',' Georgia','Hawaii', 
                    'Illinois','Indiana', 'Iowa','Maryland','Massachusetts', 
                    'Rhode Island','New York']
        
                global word
                self.word = choice(states)
                self.root.ids.my_label.text = self.word
                break_apart_word = list(self.word)
                shuffle(break_apart_word)
          
                global shuffled_word
                shuffled_word = ''
                for letter in break_apart_word:
                    shuffled_word += letter
        
                self.root.ids.my_label.text = shuffled_word
        
            def answer(self):
                if self.word == self.root.ids.entry_answer.text :
                    self.root.ids.answer_label.text= "Correct!!"
                else:
                    self.root.ids.answer_label.text = "Incorrect!!"
            global hint_count
            hint_count = 0
        
            def hint(self, count):
                global hint_count
                hint_count = count
        
                word_length = len(self.word)
         
                if count < word_length:
                    self.root.ids.hint_label.text = f'{self.hint_label["text"]} {self.word[count]}'
                    hint_count +=1
        
            def on_start(self, **kwargs): 
                self.shuffler()
        
        class Mylayout(Widget):    
          def __init__(self, **kwargs):
                super(Mylayout, self).__init__(**kwargs)
          
                self.btn1 = Button(
                    text ='hint_button', 
                    font_size ="20sp",
                    background_color =(1, 1, 1, 1), 
                    color =(1, 1, 1, 1), 
                    size =(200, 50), 
                    pos =(80, 130)
                    )
        
                buttoncallback = lambda x : self.hint(hint_count) 
                self.btn1.bind(on_press=buttoncallback)
                self.add_widget(self.btn1)
        
                
        if __name__ == '__main__':
            MainApp().run()

us_state_flaskcard_3.kv 文件

        <MyLayout>
                    
          FloatLayout:
                Label:
                    id: my_label
                    font_size: 25
                    text: 'abc'
                    pos_hint: {'x': 1.3, 'y':5}
                    size_hint: (1, 1)
                    color: 'black'
        
                TextInput:
                    id: entry_answer
                    multiline: False
                    font_size: 24
                    pos_hint: {'x': .8, 'y':4.5}
                    size_hint: (2, .4)
                    halign: "center"
        
                Button: 
                    font_size: 20
                    text: "Answer"
                    on_press: app.answer()
                    pos_hint: {'x': .8, 'y':3.5 }
                    size_hint: (2, .5)
        
                Label:
                    id: answer_label
                    font_size: 25
                    text: ''
                    pos_hint: {'x': 0.8, 'y':2.8}
                    size_hint: (2, .5)
                    color: 'black'
                    
                Button: 
                    font_size: 20
                    text: "Pick Another Word"
                    on_press: app.shuffler()
                    pos_hint: {'x': .8, 'y':2 }
                    size_hint: (2, .5)    
                    
                Label:
                    id: hint_label
                    font_size: 20
                    text: 'Hint Label'
                    pos_hint: {'x': .8, 'y':1.5}
                    size_hint: (2, .5)
                    color: 'black'

当我点击获取提示按钮时,显示错误:

     File "C:\Users\Kelvin Loh\Documents\kivyMD\kivy_venv\lib\site-packages\kivy\base.py", line 342, in dispatch_input
         post_dispatch_input(*pop(0))
       File "C:\Users\Kelvin Loh\Documents\kivyMD\kivy_venv\lib\site-packages\kivy\base.py", line 248, in post_dispatch_input
         listener.dispatch('on_motion', etype, me)
       File "kivy\_event.pyx", line 709, in kivy._event.EventDispatcher.dispatch
       File "C:\Users\Kelvin Loh\Documents\kivyMD\kivy_venv\lib\site-packages\kivy\core\window\__init__.py", line 1412, in on_motion        
         self.dispatch('on_touch_down', me)
       File "kivy\_event.pyx", line 709, in kivy._event.EventDispatcher.dispatch
       File "C:\Users\Kelvin Loh\Documents\kivyMD\kivy_venv\lib\site-packages\kivy\core\window\__init__.py", line 1428, in on_touch_down    
         if w.dispatch('on_touch_down', touch):
       File "kivy\_event.pyx", line 709, in kivy._event.EventDispatcher.dispatch
       File "C:\Users\Kelvin Loh\Documents\kivyMD\kivy_venv\lib\site-packages\kivy\uix\widget.py", line 545, in on_touch_down
         if child.dispatch('on_touch_down', touch):
       File "kivy\_event.pyx", line 709, in kivy._event.EventDispatcher.dispatch
       File "C:\Users\Kelvin Loh\Documents\kivyMD\kivy_venv\lib\site-packages\kivy\uix\behaviors\button.py", line 151, in on_touch_down     
         self.dispatch('on_press')
       File "kivy\_event.pyx", line 705, in kivy._event.EventDispatcher.dispatch
       File "kivy\_event.pyx", line 1248, in kivy._event.EventObservers.dispatch
       File "kivy\_event.pyx", line 1172, in kivy._event.EventObservers._dispatch
       File "c:\Users\Kelvin Loh\Documents\kivyMD\us_state_flaskcard_3.py", line 115, in <lambda>
         buttoncallback = lambda x : self.hint(hint_count)
     AttributeError: 'Mylayout' object has no attribute 'hint'

您可以使用 get_running_app:

buttoncallback = lambda x : App.get_running_app().hint(hint_count)

此错误背后的原因在于 buttoncallback 您触发 hint 方法的位置。但是您在 App 的子 class 中定义了该方法,即 MainApp。因此,如果您想从 Mylayout class 访问该方法,您必须首先访问 运行 应用程序实例,您可以按如下方式执行,

        app = App.get_running_app()
        buttoncallback = lambda x : app.hint(hint_count)
        self.btn1.bind(on_press=buttoncallback)

此外,也许您可​​能需要对方法进行一些更改 hint

    def hint(self, count):
        global hint_count
        hint_count = count

        word_length = len(self.word)

        if count < word_length:
            self.root.ids.hint_label.text = f'{self.word[count]}'
            hint_count +=1