'Kivy : AttributeError: 'Mylayout' object has no attribute 'hint'
I'm new to python and I am developing a US states flashcard with Kivy. The flashcard will shuffle the US states letter, the user will need to input the answer. When the user is not sure, he may click the Get Hint button, the flashcard will display a letter, the user may click for another letter until all letters are shown.
us_state_flaskcard_3.py file
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 file
<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'
When I click the Get Hint Button, the error shown:
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'
Solution 1:[1]
The reason behind this error lies in buttoncallback where you are triggering hint method. But you defined that method in the App's subclass namely, MainApp. So if you want to access that method from the Mylayout class, you have to first access the running app instance which you might do as follows,
app = App.get_running_app()
buttoncallback = lambda x : app.hint(hint_count)
self.btn1.bind(on_press=buttoncallback)
Also, perhaps you may need some change in method 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
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | ApuCoder |
