I am trying to create customized ToggleButtons in Kivy. For the most part I have succeeded except when I pair them into group. When one of the buttons is pressed down and I press onto another, the color of the formerly pressed button won't return to normal, unless I hover over it. Is there a way to make it return to it's color, when it gets unpressed by clinking another button in the group?
Please help out.
Here is the code:
from kivy.app import App
from kivy.graphics import RoundedRectangle, Color
from kivy.uix.behaviors import ButtonBehavior, ToggleButtonBehavior
from kivy.uix.button import Button
from kivy.uix.togglebutton import ToggleButton
from kivy.uix.widget import Widget
from kivy.lang import Builder
from kivy.animation import Animation
from kivymd.uix.behaviors import HoverBehavior
from kivy.properties import ObjectProperty
import time
Builder.load_file('rounding_button.kv')
class MyLayout(Widget):
def unlock_button(self):
if self.ids.disabled_button_2.disabled:
self.ids.disabled_button_2.disabled = False
else:
self.ids.disabled_button_2.disabled = True
@staticmethod
def run_method():
time.sleep(3)
class RoundedButton(Button, ButtonBehavior, HoverBehavior):
button_image = ObjectProperty(None) # Object property for picture in the button
def __init__(self, **kwargs):
super(RoundedButton, self).__init__(**kwargs)
self.hover_anim = None
self.press_anim = None
self.image_anim = None
self.text = ""
self.font_size = 50
self.background_color = (0, 0, 0, 0)
self.disabled = True
def on_press(self, *args):
self.press_anim = Animation(col=(51/255, 26/255, 0, 1/2), duration=0.15) # Color for pressed button
self.press_anim.start(self)
self.image_anim = Animation(color=(102 / 255, 61 / 255, 0, 1), duration=0.15) # Color for picture when button pressed
self.image_anim.start(self.button_image)
def on_release(self, *args):
self.press_anim = Animation(col=(158/255, 87/255, 0, 1), duration=0.15) # Color after button is released
self.press_anim.start(self)
self.image_anim = Animation(color=(1, 1, 1, 1), duration=0.15) # Color for picture when button released
self.image_anim.start(self.button_image)
def on_enter(self, *args):
if not self.disabled:
print("Hovered!")
self.hover_anim = Animation(col=(102/255, 61/255, 0, 1), duration=0.15) # Color when hovered over button
self.hover_anim.start(self)
self.image_anim = Animation(color=(102 / 255, 61 / 255, 0, 1), duration=0.15) # Color for picture when hovered over
self.image_anim.start(self.button_image)
def on_leave(self, *args):
if not self.disabled:
print("Moved away!")
self.hover_anim = Animation(col=(158/255, 87/255, 0, 1), duration=0.15) # Color when moved away from button
self.hover_anim.start(self)
self.image_anim = Animation(color=(1, 1, 1, 1), duration=0.15) # Color for picture when moved away from button
self.image_anim.start(self.button_image)
class RoundedToggleButton(ToggleButton, ToggleButtonBehavior, HoverBehavior):
toggle_button_image = ObjectProperty(None)
def __init__(self, **kwargs):
super(RoundedToggleButton, self).__init__(**kwargs)
self.down_anim = None
self.hover_anim = None
def on_press(self):
pass
def on_release(self):
pass
def on_state(self, widget, value):
if value == "down":
self.down_anim = Animation(col=(0, 134/255, 179/255, 1), duration=0.2)
self.down_anim.start(self)
else:
self.down_anim = Animation(col=(0, 191/255, 1, 1), duration=0.2)
self.hover_anim.start(self)
def on_enter(self, *args):
self.hover_anim = Animation(col=(128/255, 223/255, 1, 1), duration=0.15) # Color when hovered over button
self.hover_anim.start(self)
def on_leave(self):
if self.state == "normal":
self.hover_anim = Animation(col=(0, 191/255, 1, 1), duration=0.15) # Color when moved away from button
self.hover_anim.start(self)
else:
self.hover_anim = Animation(col=(0, 134/255, 179/255, 1), duration=0.15) # Color when moved away from button
self.hover_anim.start(self)
class AwesomeApp(App):
def build(self):
return MyLayout()
if __name__ == '__main__':
AwesomeApp().run()
kv file:
<RoundedButton>
button_image: button_image
id: disabled_button
col: (158/255, 87/255, 0, 1)
canvas.before:
Color:
rgba: (51/255, 26/255, 0, 1/2) if self.disabled else self.col
RoundedRectangle:
size: self.size
pos: self.pos
radius: [32]
BoxLayout:
size: self.parent.size
Image:
id: button_image
source: '/Users/f22daniel/PycharmProjects/Griraffe/smart_contract_development/Kivy_App/copy_link.png'
center_x: self.parent.center_x
center_y: self.parent.center_y
pos_hint: {"center_x": 0.5, "center_y": 0.5}
keep_ratio: True
allow_stretch: True
color: (51/255, 26/255, 0, 1/2) if disabled_button.disabled else (1,1,1,1)
<RoundedToggleButton>
toggle_button_image: toggle_button_image
id: toggle_button_image
col: (0, 191/255, 1, 1)
background_color: (0, 0, 0, 0)
canvas.before:
Color:
rgba: self.col
RoundedRectangle:
size: self.size
pos: self.pos
radius: [42]
<MyLayout>
BoxLayout:
orientation: 'vertical'
size: root.width, root.height
padding: 5
spacing: 5
Button:
text: 'Submit'
on_release: root.unlock_button()
font_size: 32
background_normal: ''
background_color: (0,0,1,1)
RoundedButton:
id: disabled_button_2
on_release: root.run_method()
BoxLayout:
orientation: 'horizontal'
size: root.width, root.height
padding: 2
spacing: 2
RoundedToggleButton:
group: "toggles"
RoundedToggleButton:
group: "toggles"
RoundedToggleButton:
group: "toggles"
I need the formally pressed button to return to it's original color, when another one in the group is pressed.
In the "on_state" method of your toggle button replace self.hover_anim.start(self)
with self.down_anim.start(self)
in the "else" branch and you should get the correct behavior.