Kivy如何赋予所有对象相同的基本功能

时间:2019-04-24 12:19:35

标签: python inheritance button kivy

可以说我创建了一个名为MyButton的自定义Button类。我希望所有创建的MyButton在按下时都播放相同的声音。但是我还想为特定的按钮添加不同的功能,例如,我想要一些按钮来更改标签文本,但我也希望它们播放那种声音。有没有一种通过继承来做到这一点的方法,所以我不必记住必须为每个创建的按钮添加播放声音功能吗?

编辑:假设我有一个类MyButton声明为波纹管:

class MyButton(Button):

    def generic_function_for_all_buttons(self):
        print('GENERIC FUNCTION')

现在,当我尝试在代码中的其他地方创建MyButton时:

class TestClass(BoxLayout):
    def __init__(**kwargs):
        self.buttons = []
        self.set_layout()

    def button_action(self,button):
        button.generic_function_for_all_buttons()
        print(button.text)

    def set_layout(self):
        for i in range(0,100):
            button = MyButton(text=i)
            button.on_press = functools.partial(button_action, button)
            self.buttons.append(button)
            self.add_widget(button)

这不是可运行的代码,只是我想要实现的演示。现在,每次我按下TestClass中的MyButton时,它都会打印GENERIC FUNCTION和基于按下哪个按钮的0-99之间的数字。但是我不得不添加button.generic_function_for_all_buttons()行,如果可能的话,我想避免这样做。如果这100个按钮中的每个按钮都有自己不同的操作,例如:

def action_1(self,button):
    button.generic_function_for_all_buttons()
    print('1')
def action_2(self,button):
    button.generic_function_for_all_buttons()
    print('2')
def action_3(self,button):
    button.generic_function_for_all_buttons()
    print('3')
...

那个button.generic_function_for_all_buttons()是我要避免的100行代码。我认为继承一定有可能,例如,我向MyButton类添加on_press方法,如下所示:

class MyButton(Button):

    def on_press(self):
        print('GENERIC FUNCTION')

但是它只是忽略了它。

2 个答案:

答案 0 :(得分:0)

我将创建一个名为MyButton的基类,并创建从MyButton继承的子按钮类。

然后使用“继承和多态”,可以在所有子按钮上使属性和方法(例如声音)保持相同,但是具有不同的标签,而不必为每个子按钮具有唯一的属性。

由于属性具有相同的名称,多态也将允许您遍历所有子代。

请参阅链接的文章,对此进行更多描述:

https://www.pythonspot.com/polymorphism/

答案 1 :(得分:0)

解决方案

  • on_touch_down中实施class MyButton方法
  • 使用collide_point()函数检查碰撞

摘要

class MyButton(Button):
    def on_touch_down(self, touch):
        if self.collide_point(*touch.pos):
            print('GENERIC FUNCTION')
            print(f"MyButton.text={self.text}")
            return True    # consumed touch and stop propagation / bubbling
        return super(MyButton, self).on_touch_down(touch)


class TestClass(GridLayout):
    def __init__(self, **kwargs):
        super(TestClass, self).__init__(**kwargs)
        self.cols = 20
        self.buttons = []
        self.set_layout()

    def set_layout(self):
        for i in range(0,100):
            button = MyButton(text=str(i))
            self.buttons.append(button)
            self.add_widget(button)

Kivy » Touch event basics

  

默认情况下,触摸事件将分派给所有当前显示的事件   小部件。这意味着小部件会接收触摸事件,无论它是否发生   不在他们的物理区域内。

     

...

     

为了提供最大的灵活性,Kivy派遣了   所有小部件的事件,并让他们决定如何对它们做出反应。   如果您只想响应小部件内的触摸事件,则可以   只需检查:

def on_touch_down(self, touch):
    if self.collide_point(*touch.pos):
        # The touch has occurred inside the widgets area. Do stuff!
        pass

输出

Result