我正在尝试编写一款类似于谁希望使用Kivy语言成为百万富翁的游戏。我对小部件的动态功能有疑问。
我想要做的是,当用户单击选项按钮以选择答案时,该按钮保持按下状态一段时间,然后根据正确答案切换颜色。然后,同一屏幕应该更新,并给我提出了所有颜色已重置的新问题。这是我正在处理的代码的相关部分。忽略我有两个问题生成器的事实,一旦确定这是一个问题,我将切换到随机问题生成器。
class PlayScreen(Screen):
question = StringProperty()
question_id = StringProperty()
option_a = StringProperty()
option_b = StringProperty()
option_c = StringProperty()
option_d = StringProperty()
def __init__(self, **kwargs):
super(PlayScreen, self).__init__(**kwargs)
self.Questions = dict([('id12345', "What is the capital city of Azerbaijan"), ('idd5', "What is the capital city of Turkey")])
self.Answer_Set = dict([('id12345', ["Ganja", "Baku", "Lankaran", "Ghakh"]), ('idd5', ["Istanbul", "Tiflis", "Ankara", "Izmir"])])
self.Correct_Answers = dict([('id12345', "Baku"), ('idd5', "Ankara")])
self.Question_IDs = list(self.Questions.keys())
self.question_builder()
def question_builder(self):
self.question_id =self.Question_IDs[0] #randint(0, len(self.Questions))
self.question = self.Questions[self.question_id]
self.option_a = self.Answer_Set[self.question_id][0]
self.option_b = self.Answer_Set[self.question_id][1]
self.option_c = self.Answer_Set[self.question_id][2]
self.option_d = self.Answer_Set[self.question_id][3]
return self.question
def question_builder_2(self):
self.question_id =self.Question_IDs[1] #randint(0, len(self.Questions))
self.question = self.Questions[self.question_id]
self.option_a = self.Answer_Set[self.question_id][0]
self.option_b = self.Answer_Set[self.question_id][1]
self.option_c = self.Answer_Set[self.question_id][2]
self.option_d = self.Answer_Set[self.question_id][3]
return self.question
def checker(self, instance, question_id):
if instance.text == self.Correct_Answers[question_id]:
return True
else:
return False
Kivy_language_body = """
<PlayScreen>:
name: "play"
GridLayout:
question: root.question
question_id: root.question_id
option_a: root.option_a
option_b: root.option_b
option_c: root.option_c
option_d: root.option_d
default_color: root.default_color
id: PlayScreenGrid
cols:1
rows: 2
GridLayout:
id: q
cols: 1
rows: 1
size: root.width, root.height/2
pos_hint: {"center_x":0.5, "top":1}
canvas.before:
Color:
rgb: 1,0,0
Rectangle:
pos: self.pos
size: self.size
Label:
text: PlayScreenGrid.question
font_size: 20
GridLayout:
cols: 2
rows: 2
size: root.width, root.height/2
pos_hint: {"y":0}
Button:
id: a
text: root.option_a
font_size: 20
min_state_time: 4
on_release:
a.background_color = 1, 1, 1, 1
self.trigger_action(duration=5)
self.state = "down"
print (self.state)
self.state = "normal"
print(self.state)
if root.checker(a, root.question_id): a.background_color = 1,1,0,1
else: a.background_color = 100,0,0,0.5
self.parent._trigger_layout()
root.question_builder_2()
Button:
id: b
text: root.option_b
font_size: 20
on_release:
self.state = "down"
self.state = app.timer()
if root.checker(b, root.question_id): b.background_color = 1,1,0,1
else: b.background_color = 100,0,0,0.5
Button:
id: c
text: root.option_c
font_size: 20
on_release:
self.state = "down"
app.timer()
self.state = "normal"
if root.checker(c, root.question_id): c.background_color = 1,1,0,1
else: c.background_color = 100,0,0,0.5
app.timer()
c.background_color = 1,1,1,1
app.timer()
if root.checker(c, root.question_id): root.question_builder_2()
Button:
id: d
text: root.option_d
font_size: 20
on_release:
self.state = "down"
app.timer()
self.state = "normal"
if root.checker(d, root.question_id): d.background_color = 1,1,0,1
else: d.background_color = 100,0,0,0.5
app.timer()
d.background_color = 1,1,1,1
app.timer()
if root.checker(d, root.question_id):
root.question_builder_2()
"""
答案 0 :(得分:0)
我上面提到的问题的解决方案很丑
class Countdown(Label):
a = NumericProperty(1) # seconds for button to remain in down state before the answer is revealed
b = NumericProperty(0.5) # seconds for button to remain in red or green color after answer is revealed before the next action
def __init__(self, instance, background_color, correct):
super(Countdown, self).__init__()
self.intance = instance
self.background_color = background_color
self.correct = correct
def start(self,):
Animation.cancel_all(self) # stop any current animations
self.anim = Animation(a=0, duration=self.a)
self.anim.bind(on_complete=self.finish_callback)
self.anim.start(self)
def start_2(self):
self.anime = Animation(a=0, duration=self.b)
self.anime.bind(on_complete=self.open_popup)
self.anime.start(self)
def finish_callback(self, animation, incr_crude_clock):
self.instance.background_color = self.background_color # color based on answer
self.start_2()
def open_popup(self, animation, incr_crude_clock):
if self.correct:
Factory.CorrectPopup().open() # custom popup appears if answered correctly
else:
Factory.WrongPopup().open() # custom popup appears if answered wrong
def on_a(self, instance, value):
self.instance.state = "down"
for button in self.instance.parent.children: # disable all other buttons to prevent user from clicking them randomly
if hasattr(button, 'id'):
if button.id != self.instance.id:
button.disabled = True
# Basic grid with question and 4 answer choices:
class PlayGrid(FloatLayout):
def __init__(self, **kwargs):
self.clear_widgets()
super(PlayGrid, self).__init__(**kwargs)
self.question = StringProperty()
self.id = 'plygrd'
self.cols = 1
self.question_grid = GridLayout()
self.answer_grid = GridLayout()
self.answer_grid.id = 'ansgrd'
self.button_grid = FloatLayout()
self.answer_grid.cols = 2
self.answer_grid.rows = 2
self.answer_grid.size_hint = 1, 0.5
self.answer_grid.pos_hint = {'y': 0}
self.question_grid.size_hint = 1, 0.5
self.question_grid.cols = 1
self.question_grid.rows = 1
self.question_grid.pos_hint = {'center_y': 0.5}
self.question_grid.pos_hint = {'center_x': 0.5}
self.question_grid.pos_hint = {'top': 0.85}
self.question_builder()
self.question_grid.question_panel = Label(text=self.question, id=self.question_id, font_size=50,
halign="center", valign='middle')
self.question_grid.clock = Countdown(None, None, False)
self.question_grid.add_widget(self.question_grid.question_panel)
self.add_widget(self.button_grid)
self.add_widget(self.question_grid)
self.add_widget(self.answer_grid)
self.builder()
def builder(self):
for i in range(4):
setattr(self.answer_grid, 'button_'+str(i), Button(text=Answer_Set[self.question_id][i], font_size=40, id='option_'+str(i), background_color=[100, 10, 0, 0.5]))
getattr(self.answer_grid,'button_'+str(i)).bind(on_press=self.starter)
self.answer_grid.add_widget(getattr(self.answer_grid,'button_'+str(i)))
def starter(self, instance):
if instance.text == Correct_Answers[self.question_id]:
self.calculate_score(correct=True)
instance.parent.parent.question_grid.clock.instance = instance
instance.parent.parent.question_grid.clock.background_color = [0,1,0,1]
instance.parent.parent.question_grid.clock.correct = True
instance.parent.parent.question_grid.clock.start()
else:
self.calculate_score(correct=False)
instance.parent.parent.question_grid.clock.instance = instance
instance.parent.parent.question_grid.clock.background_color = [1,0,0,1]
instance.parent.parent.question_grid.clock.correct = False
instance.parent.parent.question_grid.clock.start()
def question_builder(self):
while True:
self.question_id = Question_IDs[randint(0, len(Question_IDs)-1)]
if self.question_id not in _cache:
_cache.append(self.question_id)
break
self.question = Questions[self.question_id]