【问题标题】:Python Kivy: how to call a function on button click?Python Kivy:如何在按钮单击时调用函数?
【发布时间】: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

【问题讨论】:

    标签: python function button kivy


    【解决方案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()
          

          它应该可以工作

          【讨论】:

            猜你喜欢
            • 2020-07-29
            • 2020-12-23
            • 1970-01-01
            • 2021-12-31
            • 2013-02-26
            • 2014-01-11
            • 1970-01-01
            • 1970-01-01
            • 2021-05-05
            相关资源
            最近更新 更多