为什么在Kivy中需要括号而在Python中不需要括号?

时间:2014-06-18 22:12:15

标签: python popup kivy

如果我想在任何程序中向弹出窗口添加on_press事件,我可以直接在python中或使用kv语言进行。

如果我使用Python,例如

from kivy.app import App
from kivy.uix.popup import Popup
from kivy.uix.button import Button

class SomePopup(Popup):
    pass

class SomeBox(Box):
    popup = SomePopup()
    popup.title = 'anything'
    popup.content = Button(text='anytext', on_press=popup.dismiss)

在KV语言中,假设我制作相同的弹出窗口,那就是。

<SomePopup>
    title: 'anything'
    content: popupContent
    Button:
        id: popupContent
        text: 'anytext'
        on_press: root.dismiss()

所以,在python中,我必须使用on_press=popup.dismiss和kv语言on_press: root_dismiss()

我不明白为什么用kivy语言我应该使用括号而不是python。你能帮帮我吗?

2 个答案:

答案 0 :(得分:7)

虽然两者都实现了相同的目标,但是kv和Python以不同的方式完成它们。

在Python中,当你Button(text='anytext', on_press=popup.dismiss)时,你实际上是在告诉kivy:当发生新闻时,请调用popup.dismiss方法。也就是说,你正在传递一个对象(在这种情况下是一种类方法),kivy会在正确的时间调用它。

在kv中,当你执行on_press: root.dismiss()时,当发生新闻事件时,kivy将执行冒号后的任何文本(在这种情况下为root.dismiss())。所以你需要在那个文本中自己调用root.dismiss()

答案 1 :(得分:1)

详细说明:当您将回调代码放入kv时,它就像制作一个lambda。

所以这个kv代码:

on_press: popup.dismiss()

等同于以下Python代码:

Button(text='anytext', on_press=lambda *args: popup.dismiss())

on_press=popup.dismiss工作的唯一原因是因为Popup.dismiss()吞下额外的参数(Button实例作为第一个参数传递)。所以在这种情况下,似乎两者是等价的,但它们通常不是。

获取此代码,例如:

def callback():
    pass

button = Button(on_press=callback)

当按下Button时,它会调用callback(self) - 这将引发异常,因为callback不带参数。

相比之下,此代码的作用类似于dismiss

def callback(*args, **kwargs):
    pass

button = Button(on_press=callback)

当然,在kv:

on_press: callback()

......无论您使用哪种callback定义,它都能正常工作。