I want to pause or wait in code until user make change/decision (press ToggleButton) in Gui I found library asynckivy, but I don't know how to implement it on all buttons simultaneously and if any is pressed, continue. I tried some scheduling through Clock but not working or I did it wrong
Python code
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import *
from kivy.lang import Builder
from kivy.clock import Clock
from kivy.uix.behaviors import ToggleButtonBehavior
class FightScreen(Screen):
player_action_pick = StringProperty(rebind=True, allownone=True)
def __init__(self, **kwargs):
super(FightScreen, self).__init__(**kwargs)
self.af_init = Clock.create_trigger(self._init)
self.player_action_pick = None
self.af_init()
self.starting_hit = "Enemy"
def _init(self, dt):
self.app = App.get_running_app()
def fight(self, *args):
hero_alive = True
enemy_alive = True
def enemy_move():
# something
return hero_alive
def player_move():
# NEED SOLUTION HERE
# something like wait until any of ToggleButtonBehavior.get_widgets('player_action') is down
# than reset button state like button.state = 'normal'
# something
return enemy_alive
# while player.health > 0 and enemy.health > 0:
if self.starting_hit == "Enemy":
print("Enemy move")
if not enemy_move():
print("Player dead")
elif not player_move():
print("Enemy dead")
else:
print("Player move")
def on_enter(self, *args):
self.fight()
def player_action(self, stat):
self.player_action_pick = stat
class ScreenManagement(ScreenManager):
pass
class Design(App):
def __init__(self, **kwargs):
super(Design, self).__init__(**kwargs)
# Construct app
def build(self):
# design constructor
kv = Builder.load_file('AppDesign.kv')
return kv
if __name__ == "__main__":
Design().run()
kivy code
ScreenManagement:
id: screen_manager
FightScreen:
name: 'FightScreen'
manager: screen_manager
id: fight_screen
<PlayerActionButton@ToggleButton>
size_hint: .3, .1
background_color: '#654321'
text: "Attack!"
<FightScreen>
FloatLayout:
GridLayout:
cols: 1
rows: 4
PlayerActionButton:
group: 'player_action'
on_state:
if self.state == 'down': \
root.player_action('programming_stat')
PlayerActionButton:
group: 'player_action'
on_state:
if self.state == 'down': \
root.player_action('design_stat')
PlayerActionButton:
group: 'player_action'
on_state:
if self.state == 'down': \
root.player_action('creativity_stat')
PlayerActionButton:
group: 'player_action'
on_state:
if self.state == 'down': \
root.player_action('heal')
If you use asynckivy
, the code would be:
import asynckivy as ak
class FightScreen(Screen):
async def fight(self, *args):
hero_alive = True
enemy_alive = True
def enemy_move():
# something
return hero_alive
async def player_move():
buttons = ToggleButtonBehavior.get_widgets('player_action')
await ak.or_from_iterable(
ak.event(button, 'state') for button in buttons)
for button in buttons:
button.state = 'normal'
return enemy_alive
# while player.health > 0 and enemy.health > 0:
if self.starting_hit == "Enemy":
print("Enemy move")
if not enemy_move():
print("Player dead")
elif not await player_move():
print("Enemy dead")
else:
print('AAAA')
else:
print("Player move")
def on_enter(self, *args):
ak.start_soon(self.fight())