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
我是 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