I started learning Kivy recently and I can't believe that such simple things like creating buttons and adding basic behaviours to them like hovering over them etc are so difficult and unintuitive.
My question is how can I make the border appear around a button when I hover over it with a mouse?
I have this simple "main menu" design and I want to make the button change its appearance as on the screen below:
The only thing that I can't figure out is how to make the border appear when hovering over the buttons (although finding out how to make a hover effect in Kivy took also a lot of time...).
I've literally spent the last few hours googling it and searching for the solution here on Stack Overflow but I wasn't able to find anything related to this problem.
I know that I can add borders and make a button that is surrounded with borders by including the following code in my Kivy file:
canvas.before:
Color:
rgba: #some color
Line:
rounded_rectangle: (self.pos[0], self.pos[1], self.size[0], self.size[1], self.border_radius)
width: 2
But I don't know how to get canvas.before in my ButtonMenu class updated after a hover.
I also tried to combine RoundedRectangle and Line so that the border is already added even when the button is black and only the background_color is updated, but it didn't really give me the results that I want.
Below is my code in Python file:
from kivy.lang.builder import Builder
from kivy.properties import ListProperty
from kivy.uix.button import Button
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.core.window import Window
from kivymd.uix.behaviors.hover_behavior import HoverBehavior
Window.size = (1280, 720)
class MainMenu(Screen):
pass
class WindowManager(ScreenManager):
pass
class ButtonMenu(Button, HoverBehavior):
background = ListProperty((0, 0, 0, 1))
color = ListProperty((1, 1, 1, 1))
def on_enter(self):
self.background = (1, 222/255, 89/255, 1)
self.color = (0, 0, 0, 1)
def on_leave(self):
self.background = (0, 0, 0, 1)
self.color = (1, 1, 1, 1)
class TicTacToeUltimateApp(App):
def build(self):
return Builder.load_file('tictactoeultimate.kv')
if __name__ == '__main__':
TicTacToeUltimateApp().run()
My Kivy file:
WindowManager:
MainMenu:
<MainMenu>:
name: 'main_menu'
FloatLayout:
orientation: 'horizontal'
size: 1280, 720
canvas.before:
Color:
rgba: (1, 222/255, 89/255, 1)
Rectangle:
pos: self.pos
size: self.size
ButtonMenu:
text: 'PLAY'
pos_hint: {'center_x': .5, 'center_y': .5}
ButtonMenu:
text: 'SETTINGS'
pos_hint: {'center_x': .5, 'center_y': .35}
ButtonMenu:
text: 'ABOUT'
pos_hint: {'center_x': .5, 'center_y': .2}
<ButtonMenu>
background_color: 0, 0, 0, 0
background_normal: ''
size_hint: 0.3, 0.11
font_size: 26
font_name: 'Roboto'
bold: True
canvas.before:
Color:
rgba: self.background
RoundedRectangle:
size: self.size
pos: self.pos
radius: [28]
Line:
rounded_rectangle: (self.pos[0], self.pos[1], self.size[0], self.size[1], self.border_radius)
width: 2
`
To get the hover effect I followed this tutorial, but it just shows how to get the change of the background color to be updated, not how to add borders:
https://www.youtube.com/watch?v=fKFpxud0O6c
Furthermore, I found this video on how to create a border around a button, but it just shows how to create a static button with a border. Basically, I still don't know how to make this border to be updated:
https://www.youtube.com/watch?v=Xv57jB_Xvqo&t=366s
Thank you in advance for looking into it.
Sometimes the simplest solutions slip our minds and we focus on difficult things. Following this way, the border appears when hovering over a button in Kivy
1. Add a second Color in your canvas.before:
. So write: Color: rgba: (0, 0, 0, 1)
2. In your rounded_rectangle
of Line
, remove self.border_radius
and then write , 28
WindowManager:
MainMenu:
<MainMenu>:
name: 'main_menu'
FloatLayout:
orientation: 'horizontal'
size: 1280, 720
canvas.before:
Color:
rgba: (1, 222/255, 89/255, 1)
Rectangle:
pos: self.pos
size: self.size
ButtonMenu:
text: 'PLAY'
pos_hint: {'center_x': .5, 'center_y': .5}
ButtonMenu:
text: 'SETTINGS'
pos_hint: {'center_x': .5, 'center_y': .35}
ButtonMenu:
text: 'ABOUT'
pos_hint: {'center_x': .5, 'center_y': .2}
<ButtonMenu>
background_color: 0, 0, 0, 0
background_normal: ''
size_hint: 0.3, 0.11
font_size: 26
font_name: 'Roboto'
bold: True
canvas.before:
Color:
rgba: self.background
RoundedRectangle:
size: self.size
pos: self.pos
radius: [28]
Color:
rgba: (0, 0, 0, 1) # separate color for line border
Line:
rounded_rectangle: (self.pos[0], self.pos[1], self.size[0], self.size[1], 28)
width: 2