Mike Delta
Mike Delta

Reputation: 808

Python Kivy: how to call a function on button click?

i'm pretty new at using kivy library.

I have an app.py file and an app.kv file , my problem is that I can't call a function on button press.

app.py:

import kivy
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button

class Launch(BoxLayout):
    def __init__(self, **kwargs):
        super(Launch, self).__init__(**kwargs)

    def say_hello(self):
        print "hello"


class App(App):
    def build(self):
        return Launch()


if __name__ == '__main__':
    App().run()

app.kv:

#:kivy 1.9.1

<Launch>:
    BoxLayout:
        Button:
            size:(80,80)
            size_hint:(None,None)
            text:"Click me"
            on_press: say_hello

Upvotes: 11

Views: 39903

Answers (9)

Swyam Pradhan
Swyam Pradhan

Reputation: 11

from kivy.app import App
from kivy.uix.button import Button

class MyApp(App):
    def build(self):
        return Button(text="Hello, Kivy!", on_press=self.on_button_click)

    def on_button_click(self, instance):
        instance.text = "Button Pressed!"

if __name__ == '__main__':
    MyApp().run()

Upvotes: 1

frank
frank

Reputation: 11

function with object as argument in kv-file

in kv:

on_press: root.say_hello(self)

in py:

def say_hello(self,obj):
    print(obj)

Upvotes: 1

Tomasz Lipiński
Tomasz Lipiński

Reputation: 85

If you would like to add function to any element in Kivy just use logic like here.

In your .py file:

class LoginButton(Button):

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.text = "Login"

    def login(self):
        print("logged_in") 

And then in .kv file:

LoginButton:
            id: "login"
            on_press: self.login()
            size_hint: None, None
            size: 500, 50
            pos_hint: {"center_x": 0.5}

It works for me :)

Upvotes: 1

Edoardo Vignati
Edoardo Vignati

Reputation: 553

For anyone is looking for a pure Python approach here is a general example.

To call a function without arguments:

def my_function(instance):
   ...

my_button.bind(on_press=my_function)

To call a function with arguments:

from functools import partial

def my_function(instance, myarg):
   ...

my_button.bind(on_press=partial(my_function,"a string"))

Upvotes: 1

MD. Saiful Islam
MD. Saiful Islam

Reputation: 459

you just added root before say_hello() function. like this

on_press:
    root.say_hello()

it should working

Upvotes: 0

D. Tulloch
D. Tulloch

Reputation: 21

I believe that the solution utilizing the bind function (given by Ender Look) will lead to the following error:

TypeError: pressed() takes 1 positional argument but 2 were given

To solve this issue you have to allow the say_hello() module to accept the touch input as well, although it isn't needed.

Upvotes: 2

R Yeshwanth
R Yeshwanth

Reputation: 31

from kivy.app import App

from kivy.uix.button import Button

from kivy.uix.label import Label

class Test(App):

def press(self,instance):
    print("Pressed")
def build(self):
    butt=Button(text="Click")
    butt.bind(on_press=self.press) #dont use brackets while calling function
    return butt

Test().run()

Upvotes: 3

Ender Look
Ender Look

Reputation: 2401

Mode:.kv

It's very simple, say_hello belongs to the Launch class so in order to use it in your .kv file you have to write root.say_hello. Note that say_hello is a function that you want to execute so you don't have to forget the () ---> root.say_hello().

Also, if say_hello were in App class you should use App.say_hello() because it belongs to the app. (Note: even if your App class were class MyFantasicApp(App): it would always be App.say_hello() or app.say_hello() I don't remember, sorry).

#:kivy 1.9.1

<Launch>:
    BoxLayout:
        Button:
            size:(80,80)
            size_hint:(None,None)
            text:"Click me"
            on_press: root.say_hello()

Mode: .py

You can bind the function.

from kivy.uix.button import Button # You would need futhermore this
class Launch(BoxLayout):
    def __init__(self, **kwargs):
        super(Launch, self).__init__(**kwargs)
        mybutton = Button(
                            text = 'Click me',
                            size = (80,80),
                            size_hint = (None,None)
                          )
        mybutton.bind(on_press = self.say_hello) # Note: here say_hello doesn't have brackets.
        Launch.add_widget(mybutton)

    def say_hello(self):
        print "hello"

Why use bind? Sorry, no idea. But you it's used in the kivy guide.

Upvotes: 13

inclement
inclement

Reputation: 29460

say_hello is a method of the Launch class. In your kv rule, the Launch class is the root widget, so it can be accessed using the root keyword:

on_press: root.say_hello()

Note also that you have to actually call the function, not just write its name - everything to the right of the colon is normal Python code.

Upvotes: 2

Related Questions