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

Posted

技术标签:

【中文标题】Python Kivy:如何在按钮单击时调用函数?【英文标题】:Python Kivy: how to call a function on button click? 【发布时间】:2018-03-03 06:46:33 【问题描述】:

我对使用 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

【问题讨论】:

【参考方案1】:

模式:.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

你可以bind这个函数。

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?对不起,不知道。但是你在the kivy guide中使用它。

【讨论】:

如果你创建一个单独的MyButton 类,你不必绑定它,你可以在其中定义一个方法on_press()。可能工作量太大,除非您对 Button 有其他事情要做。【参考方案2】:
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】:

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

on_press: root.say_hello()

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

【讨论】:

【参考方案4】:

我相信使用绑定函数的解决方案(由 Ender Look 提供)会导致以下错误:

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

要解决此问题,您必须允许 say_hello() 模块也接受触摸输入,尽管这不是必需的。

【讨论】:

请进一步澄清您的答案。如果您使用您认为不起作用的代码部分,它会更有帮助。谢谢 @EnriqueBet 我尝试了上面的代码并不断收到我提到的错误。我允许 say_hello() 接受另一个参数来解释 Touch 事件,然后一切正常。还有其他解释吗?我是 Kivy 的新手,只是在挑战自己不要使用 kv 文件,这样我在这里学到的任何东西都可以更容易地与其他 OOP 语言一起使用。【参考方案5】:

对于任何正在寻找纯 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"))

【讨论】:

【参考方案6】:

如果您想为 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

它对我有用:)

【讨论】:

【参考方案7】:

您刚刚在 say_hello() 函数之前添加了 root。 像这样

on_press:
    root.say_hello()

它应该可以工作

【讨论】:

以上是关于Python Kivy:如何在按钮单击时调用函数?的主要内容,如果未能解决你的问题,请参考以下文章

在 discord_components (python) 中单击按钮时调用 python 函数

如何在动态操作中单击按钮时调用Oracle APEX中的javascript函数?

Django admin:如何在单击自定义按钮时调用操作?

在 Bootstrap 模式中单击按钮时调用 JS 函数

在父按钮单击时调用并执行多个子函数

如何在 Vuetify.js 中单击附加图标时调用函数?