Search code examples
kivykivy-languagebuilder

Using builder in Kivy


I want to create a simple app that has GUI with a button that allows me to vibrate an android phone. Im using a .kv file for the layout and the Builder in my .yp file

.py file:

from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.gridlayout import GridLayout
from kivy.lang import Builder
from plyer import vibrator


class AndroidApp(GridLayout):
    def vibrate(self):
        vibrator.vibrate()


kv = Builder.load_file("android_app.kv")


class MainApp(App):
    def build(self):
        return kv


if __name__ == "__main__":
    MainApp().run()

.kv file:

#:import utils kivy.utils
<AndroidApp>:
    FloatLayout:
        canvas.before:
            Color:
                rgb: utils.get_color_from_hex("#ffffff")
            Rectangle:
                size: self.size
                pos: self.pos
        GridLayout:
            rows: 1
            cols: 2
            Label:
                text:"Android Vibrate"

            Button:
                text:"Android Vibrate"
                on_press:
                    root.vibrate()

When I try to run the app, I get the following error:

enter image description here

This should be straightforward app but somehow I find a way to make it crash. The android_app.py & .kv files are in the same folder. Any ideas why the window wont be created? I aprreciate any help. Thanks, Alex


Solution

  • You have to return the main class, not the result from building. Here I'm using Builder.load_string() for convenience, and not importing player, but otherwise the only substantive change is that I changed return kv to return AndroidApp()

    from kivy.app import App
    from kivy.uix.floatlayout import FloatLayout
    from kivy.uix.gridlayout import GridLayout
    from kivy.lang import Builder
    
    KV = '''
    #:import utils kivy.utils
    <AndroidApp>:
        FloatLayout:
            canvas.before:
                Color:
                    rgb: utils.get_color_from_hex("#ffffff")
                Rectangle:
                    size: self.size
                    pos: self.pos
            GridLayout:
                rows: 1
                cols: 2
                Label:
                    text:"Android Vibrate"
    
                Button:
                    text:"Android Vibrate"
                    on_press:
                        root.vibrate()
    '''
    
    class AndroidApp(GridLayout):
        def vibrate(self):
            vibrator.vibrate()
    
    
    Builder.load_string(KV)
    
    
    class MainApp(App):
        def build(self):
            return AndroidApp()
    
    
    if __name__ == "__main__":
        MainApp().run()