Bind function to Kivy button

2019-04-30 10:50发布

I'm trying to bind the following function to a Button in Kivy.

def auth(self):
    print(self.username)
    if self.username == "Hendricko":
        print("self.username == Hendricko")
        popup = Popup(title="success",
            content=Label(text="Howdy !"),
            size=(100, 100),
            size_hint=(0.3, 0.3),
            auto_dismiss=False)
        popup.open()

I've tried

class Foo():
   def initUI(self):
    self.add_widget(Button(text="Auth User and Password", on_press=self.auth))

but this doesn't work. What am I doing wrong?

here is my whole code

from kivy.uix.popup import Popup
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.stacklayout import StackLayout


class LoginScreen(GridLayout):
    def __init__(self, **kwargs):
        super(LoginScreen, self).__init__(**kwargs)
        self.cols = 2
        self.row = 2
        self.add_widget(Label(text='User Name'))
        self.username = TextInput(multiline=False)
        self.add_widget(self.username)
        self.add_widget(Label(text='password'))
        self.password = TextInput(password=True, multiline=False)
        self.add_widget(self.password)
        self.hello = Button(text="hello", on_press=self.auth)
        self.add_widget(self.hello)

    def auth(self):
        if self.username == "Hendricko":
            popup = Popup(title="success",
                content=Label(text="Howdy !"),
                size=(100, 100),
                size_hint=(0.3, 0.3),
                auto_dismiss=False)
            popup.open()


class MyApp(App):
    def build(self):
        return LoginScreen()


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

4条回答
欢心
2楼-- · 2019-04-30 11:24

Replace line

self.hello = Button(text="hello", on_press=lambda a:self.auth())

of your code and use this :

self.hello = Button(text="hello", on_press=lambda a:self.auth())

Also add below line in auth function to see if its called :)

print "auth called"

and There are many ways to perform a particular task .Above code will be to fix your code in minimum effort , However If you would like to do it in another way . Just use code below .

from kivy.uix.popup import Popup
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.stacklayout import StackLayout


class LoginScreen(GridLayout):
    def __init__(self, **kwargs):
        super(LoginScreen, self).__init__(**kwargs)
        self.cols = 2
        self.row = 2
        self.add_widget(Label(text='User Name'))
        self.username = TextInput(multiline=False)
        self.add_widget(self.username)
        self.add_widget(Label(text='password'))
        self.password = TextInput(password=True, multiline=False)
        self.add_widget(self.password)
        self.hello = Button(text="hello")
        self.hello.bind(on_press=self.auth)
        self.add_widget(self.hello)

    def auth(self,instance):
        print "auth called"
        if self.username == "Hendricko":
            popup = Popup(title="success",
                content=Label(text="Howdy !"),
                size=(100, 100),
                size_hint=(0.3, 0.3),
                auto_dismiss=False)
            popup.open()


class MyApp(App):
    def build(self):
        return LoginScreen()


if __name__ == '__main__':
    MyApp().run()
查看更多
神经病院院长
3楼-- · 2019-04-30 11:27

If you read the Button documentation, the key seems to be to use the bind function:

def callback(instance):
    print('The button <%s> is being pressed' % instance.text)

btn1 = Button(text='Hello world 1')
btn1.bind(on_press=callback)
查看更多
狗以群分
4楼-- · 2019-04-30 11:40

I report an example of buttons created dynamically within the main class, and then triggered into a single listener:

class allMyApp(TabbedPanel):
    def __init__(self, **kwargs):
        super(allMyApp, self).__init__(**kwargs)

        #[...]

        for y in sorted(set(emissionYears)):
            btn = Button(text = y,
                         size_hint_y = None,
                         height = '48dp',
                         on_release = lambda btn: self.ids.choseEmissionDate.select(btn.text))
            btn.bind(on_press = self.sortByYear)
            self.ids.choseEmissionDate.add_widget(btn)

    def sortByYear(self, instance):
        year = instance.text
        print(year)
查看更多
做个烂人
5楼-- · 2019-04-30 11:42

I don't think any of the answers are very clear. Neither explains that problem is that the callback given to on_press gets called with a parameter, the instance of button, so LoginScreen.auth must accept a parameter after the self:

def auth(self, button):
    print('button pressed:', instance)

The problem is not that on_press must be given via Button.bind or that the callback must be a function, it can be a bound method, and the docs cited by other answer and by comments link to ButtonbBhavior which indicates that OP use of on_press in constructor was fine:

self.hello = Button(text="hello", on_press=self.auth)

would have worked if auth had been as described above.

查看更多
登录 后发表回答