将功能绑定到 Kivy 按钮

Posted

技术标签:

【中文标题】将功能绑定到 Kivy 按钮【英文标题】:Bind function to Kivy button 【发布时间】:2014-06-01 08:59:03 【问题描述】:

我正在尝试将以下函数绑定到 Kivy 中的 Button

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()

我试过了

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

但这不起作用。我做错了什么?

这是我的全部代码

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()

【问题讨论】:

我猜你的类结构,但如果你能填写如何添加按钮以及如何尝试更完整地绑定到它的示例,那就太好了 - 这就是问题所在就是,auth函数在这里只是一个细节。 您是否将 auth 保留在同一个类 Foo 中?您是否使用小部件或布局来显示您的数据? 是的,对于第一篇含糊不清的帖子感到抱歉 【参考方案1】:

我认为任何答案都不是很清楚。两者都没有解释这个问题是给on_press的回调被调用了一个参数,按钮的实例,所以LoginScreen.auth必须在self之后接受一个参数:

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

问题不是 on_press 必须通过 Button.bind 给出,或者回调必须是一个函数,它可以是一个绑定方法,以及其他答案和引用的文档cmets 链接到ButtonbBhavior,这表明OP 在构造函数中使用on_press 很好:

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

如果auth 如上所述,将会起作用。

【讨论】:

【参考方案2】:

如果你看了Button documentation,关键似乎是使用bind函数:

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

btn1 = Button(text='Hello world 1')
btn1.bind(on_press=callback)

【讨论】:

bind 效果很好 - 我想知道有没有办法使用 .kv 语言来做到这一点,还是必须在 python 中完成?【参考方案3】:

换行

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

您的代码并使用它:

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

还在 auth 函数中添加以下行以查看它是否被调用:)

print "auth called"

并且有很多方法可以执行特定任务。上面的代码将以最小的努力修复您的代码,但是如果您想以另一种方式进行。只需使用下面的代码。

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()

【讨论】:

非常感谢。 @brousch 答案已修改。较早的方法是通过对代码的最小更改来修复代码。 不应该比较文本输入的值吗?使用 if self.username.text == "Hendricko" 我看不出前两行有什么区别【参考方案4】:

我报告了一个在主类中动态创建的按钮示例,然后触发到单个侦听器中:

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)

【讨论】:

以上是关于将功能绑定到 Kivy 按钮的主要内容,如果未能解决你的问题,请参考以下文章

将函数绑定到kivy中的按钮

将按钮绑定到从 Kivy 到 python 的回调

如何将参数传递给 kivy 按钮的绑定函数

Kivy - 如何在激活时将功能绑定到复选框

在 Kivy 中使用切换按钮绑定函数

kivy - 绑定弹出窗口关闭以从另一个小部件实例中运行