Python Kivy:如何在按钮单击时调用函数?

11

我对使用kivy库还比较新。

我有一个app.py文件和一个app.kv文件,我的问题是我不能在按钮按下时调用函数。

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
8个回答

13

模式:.kv

很简单,say_hello 属于 Launch 类,因此在您的 .kv 文件中使用它,您需要编写 root.say_hello。请注意,say_hello 是要执行的函数,因此不要忘记 () ---> root.say_hello()

另外,如果 say_helloApp 类中,则应使用 App.say_hello(),因为它属于应用程序。(注意:即使您的 App 类是 class MyFantasicApp(App):,它仍将始终是 App.say_hello()app.say_hello(),我记不清了,抱歉)。

#:kivy 1.9.1

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

模式:.py

您可以绑定该函数。

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"

为什么要使用 bind?抱歉,我不知道。但是在Kivy指南中使用了它。


如果您创建一个单独的MyButton类,并在其中定义一个on_press()方法,则无需绑定它。这可能需要太多的工作,除非您还有其他事情要处理按钮。 - John C

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

3
确实是非常淘气的变量名! - nikhil swami

2

say_hello 是 Launch 类的一个方法。在你的 kv 规则中,Launch 类是根部组件,因此可以使用 root 关键字进行访问:

on_press: root.say_hello()

请注意,您需要实际调用该函数,而不仅仅是写其名称-冒号右侧的所有内容都是正常的Python代码。

2

我认为使用Ender Look提供的bind函数解决方案会导致以下错误:

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

为了解决这个问题,您需要允许say_hello()模块接受触摸输入,尽管它并不是必需的。

请进一步澄清您的答案。如果您使用了您认为不起作用的代码部分,那将更有帮助。谢谢。 - EnriqueBet
@EnriqueBet 我尝试了上面的代码,但一直出现我提到的错误。我允许say_hello()接受另一个参数来解决Touch事件的问题,然后一切都正常了。还有其他的解释吗?我是Kivy的新手,只是在挑战自己不使用kv文件,这样就更容易将我在这里学到的内容与其他OOP语言结合起来使用。 - D. Tulloch

1

在kv文件中以对象为参数的函数

示例代码:

on_press: root.say_hello(self)

in py:

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

1

如果您想向Kivy中的任何元素添加功能,只需像这里一样使用逻辑。

在您的.py文件中:

class LoginButton(Button):

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

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

然后在 .kv 文件中:

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

它对我有效 :)


1
对于那些正在寻找纯Python方法的人,这里有一个通用示例。
调用不带参数的函数:
def my_function(instance):
   ...

my_button.bind(on_press=my_function)

调用带参数的函数:
from functools import partial

def my_function(instance, myarg):
   ...

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

0

你刚刚在 say_hello() 函数前面添加了 root。

on_press:
    root.say_hello()

它应该可以工作


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接