Reputation: 308
According to Kivy Doc, I can customize a kivy app look, by creating a local style.kv file that will be use instead of standard. So I edited the original file, by modifying, the behavior of the Button widget like this :
<-Button,-ToggleButton>:
canvas:
Color:
rgba: [1, 0, 0, 1] if self.state == 'normal' else [0, 0, 1, 1]
Rectangle:
pos: self.pos
size: self.size
Color:
rgba: 1, 1, 1, 1
Rectangle:
texture: self.texture
size: self.texture_size
pos: int(self.center_x - self.texture_size[0] / 2.), int(self.center_y - self.texture_size[1] / 2.)
I was hoping that buttons background's become red and change to blue when clicked. But nothings happen, and the default behavior was applied.
This is the content of my main file
from os.path import abspath, dirname, join
from kivy.app import App
from kivy.resources import resource_add_path, resource_find
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
class MainLayout(BoxLayout):
def __init__(self, **kwargs):
super(MainLayout, self).__init__(**kwargs)
self.add_widget(Button(text="Button1"))
self.add_widget(Button(text="Button2"))
class MainApp(App):
def build(self):
return MainLayout()
if __name__ == '__main__':
res_path = join(dirname(abspath(__file__)), "custom")
resource_add_path(res_path)
print("find ", resource_find("data/style.kv"))
MainApp().run()
At runtime, the local path of the style.kv is well printed.
All help is greatly appreciated!
Upvotes: 2
Views: 3148
Reputation: 31
When loading style.kv, Kivy looks for wherever the "Kivy data directory" is on the local machine's environment. It does so with an absolute filepath, not a relative filepath, so Kivy won't ever automatically load a style.kv file from any directory added with resource_add_path
.
This means if you create a custom data directory, then you must modify the environment variable KIVY_DATA_DIR
.
However, Kivy loads style.kv the moment that the Kivy package is imported. So, if you want to set this environment variable in Python, you will have to do something like
import os
# this must be written BEFORE you import anything from Kivy
os.environ['KIVY_DATA_DIR'] = 'path/to/your/custom/data/directory'
from kivy.app import App
# etc
Note that if you create a custom Kivy data directory with only a style.kv file, a lot of things will break. Hence I recommend you copy everything which exists in the default Kivy directory (which on Windows you can probably find at C:\Users\<your_username>\AppData\Local\Programs\Python\<your_python_version>\Lib\site-packages\kivy\data
; or you can just download it from the Kivy source code) and place it in your custom data directory. Then you incrementally modify the copied style.kv in your custom data directory.
If you don't want to go through all this trouble just to modify style.kv, then a simpler approach is to just do the following:
import kivy
from kivy.lang import Builder
Builder.unload_file(os.path.join(kivy.__file__, '../data/style.kv'))
Builder.load_file('path/to/your/custom/data/directory/style.kv')
# the rest of your application goes here
Upvotes: 1
Reputation: 39002
Even though the documentation says that you can customize kivy exactly the way you have attempted, it does not look like it works. However, you can get it to work by just loading your modified style.kv
using kivy.lang.Builder
.
For example:
from kivy.lang import Builder
Builder.load_string('''
<-Button,-ToggleButton>:
canvas:
Color:
rgba: [1, 0, 0, 1] if self.state == 'normal' else [0, 0, 1, 1]
Rectangle:
pos: self.pos
size: self.size
Color:
rgba: 1, 1, 1, 1
Rectangle:
texture: self.texture
size: self.texture_size
pos: int(self.center_x - self.texture_size[0] / 2.), int(self.center_y - self.texture_size[1] / 2.)
''')
from os.path import abspath, dirname, join
from kivy.app import App
from kivy.resources import resource_add_path, resource_find
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
class MainLayout(BoxLayout):
def __init__(self, **kwargs):
super(MainLayout, self).__init__(**kwargs)
self.add_widget(Button(text="Button1"))
self.add_widget(Button(text="Button2"))
class MainApp(App):
def build(self):
return MainLayout()
if __name__ == '__main__':
MainApp().run()
Upvotes: 2