Changing the background color of a Button in Kivy
Question:
I’m new to Kivy and having trouble specifying the background color of a Button. Here’s my simple example:
# custombutton.py
from kivy.app import App
from kivy.uix.widget import Widget
class MyWidget(Widget):
pass
class CustomButtonApp(App):
def build(self):
return MyWidget()
if __name__ == '__main__':
CustomButtonApp().run()
And the accompanying kv file custombutton.kv
:
#:kivy 1.7.2
<MyWidget>:
canvas:
Color:
rgb: (0.93, 0.93, 0.93)
Rectangle:
pos: self.pos
size: self.size
Button:
center: self.parent.center
font_size: 14
height: 28
background_color: (1.0, 0.0, 0.0, 1.0)
text: "I'm a Button"
I’m sure I’m missing something obvious, but I’ve been messing with this for over an hour now and getting nowhere. The button seems to get colored a hint of very dark red:
Is this not the way to specify the background color for a Button in Kivy?
Thanks!
Answers:
Ah, this is a common confusion. The problem is that Button.background_color
really works as a kind of tint, not just a block colour. Since the default background is a grey image (the one you normally see if you make an unstyled button), what you end up seeing is a red tint to that grey image – which comes out as the dark red you observe.
You can get the behaviour you want by replacing the background image to just one that’s plain white (it doesn’t have to be more than a few pixels), or by otherwise playing with the background_normal
and background_down
properties. When your background_color tints the new pure white image, you get the pure red you’re after.
I guess this isn’t so clear in the docs, I’ll try to improve it.
It’s been a while since this was first posted so maybe with updates they came up with a better solution:
Button:
background_normal: ''
background_color: 1, .3, .4, .85
Since the Button has a default grey, adding background color will only tint the button. By setting background_normal to ” that resets the default to white. From the white canvas the background_color works as you would expect.
Documentation
1) https://kivy.org/docs/api-kivy.uix.button.html?highlight=button#module-kivy.uix.button
The problem with using background_normal = ''
is that it blows away the kivy button image with raised edges/shadowing and setback. One way to get a raised button of a specific color would be to make your own atlas using gimp or other editors. However, by some trial and error I found that the Button background_color
attribute can implement a tint as well as the documented shade. In other words, it can have ‘RGB’ values > 1. So to get an exact button color with the kivy button defaulttheme for raised edges, use:
import numpy as np
# the defaulttheme for kivy buttons is grey 88,88,88
kivy_defaulttheme_color = np.array([88,88,88,256])/256
desired_button_color = np.array([78,101,115,256])/256
tintshade_color = desired_button_color / kivy_defaulttheme_color
Button(background_color = tintshade_color)
which demonstrates both a tint and a shade.
I’m new to Kivy and having trouble specifying the background color of a Button. Here’s my simple example:
# custombutton.py
from kivy.app import App
from kivy.uix.widget import Widget
class MyWidget(Widget):
pass
class CustomButtonApp(App):
def build(self):
return MyWidget()
if __name__ == '__main__':
CustomButtonApp().run()
And the accompanying kv file custombutton.kv
:
#:kivy 1.7.2
<MyWidget>:
canvas:
Color:
rgb: (0.93, 0.93, 0.93)
Rectangle:
pos: self.pos
size: self.size
Button:
center: self.parent.center
font_size: 14
height: 28
background_color: (1.0, 0.0, 0.0, 1.0)
text: "I'm a Button"
I’m sure I’m missing something obvious, but I’ve been messing with this for over an hour now and getting nowhere. The button seems to get colored a hint of very dark red:
Is this not the way to specify the background color for a Button in Kivy?
Thanks!
Ah, this is a common confusion. The problem is that Button.background_color
really works as a kind of tint, not just a block colour. Since the default background is a grey image (the one you normally see if you make an unstyled button), what you end up seeing is a red tint to that grey image – which comes out as the dark red you observe.
You can get the behaviour you want by replacing the background image to just one that’s plain white (it doesn’t have to be more than a few pixels), or by otherwise playing with the background_normal
and background_down
properties. When your background_color tints the new pure white image, you get the pure red you’re after.
I guess this isn’t so clear in the docs, I’ll try to improve it.
It’s been a while since this was first posted so maybe with updates they came up with a better solution:
Button:
background_normal: ''
background_color: 1, .3, .4, .85
Since the Button has a default grey, adding background color will only tint the button. By setting background_normal to ” that resets the default to white. From the white canvas the background_color works as you would expect.
Documentation
1) https://kivy.org/docs/api-kivy.uix.button.html?highlight=button#module-kivy.uix.button
The problem with using background_normal = ''
is that it blows away the kivy button image with raised edges/shadowing and setback. One way to get a raised button of a specific color would be to make your own atlas using gimp or other editors. However, by some trial and error I found that the Button background_color
attribute can implement a tint as well as the documented shade. In other words, it can have ‘RGB’ values > 1. So to get an exact button color with the kivy button defaulttheme for raised edges, use:
import numpy as np
# the defaulttheme for kivy buttons is grey 88,88,88
kivy_defaulttheme_color = np.array([88,88,88,256])/256
desired_button_color = np.array([78,101,115,256])/256
tintshade_color = desired_button_color / kivy_defaulttheme_color
Button(background_color = tintshade_color)
which demonstrates both a tint and a shade.