python - 将一个函数绑定(bind)到kivy中的多个动态创建的按钮?

标签 python events kivy kivy-language

问题

我想创建多个按钮并将它们绑定(bind)到一个函数。问题是,每当我单击一个按钮时,该函数就会被多次调用。看来是事件连接的问题。当我查看按下按钮时调用该函数的实例时,似乎该函数立即从每个按钮调用?!

KV代码:

...
# This is the button that I'am using
<ProjectSelectButton>:
height: 35
background_color: 0,0,1,1
on_touch_down: self.click_on_button(args[0], args[1])

...

# The buttons are added to this grid
ButtonsPlacedHere@GridLayout:
    id: active_projects
    cols: 1
    size_hint_y: None
    height: self.minimum_height
    spacing: 1
...

Python 代码:

...
class ProjectSelectButton(Button):
    def click_on_button(self, instance, touch, *args):
        print(instance)
        if touch.button == 'right':
            print(self.id, "right mouse clicked")
        else touch.buttom == 'left':
            print(self.id, "left mouse clicked")

...

# The part of my programm that creates the buttons
# projects is a dictionary
for key, project in data_manager.resource_pool.projects.items():
    print(project.project_name)
    button= ProjectSelectButton(text=project.project_name, id=key, size_hint_y=None)
    # Bind without KV-File (same result)
    # label.bind(on_touch_up=self.click_on_button)
    ids.active_projects.add_widget(button)

示例输出:

当我点击一个按钮时我得到了什么!

<guiMain.ProjectSelectButton object at 0x0BA34260>
ID01 right mouse clicked
<guiMain.ProjectSelectButton object at 0x0BA34260>
ID01 right mouse clicked
<guiMain.ProjectSelectButton object at 0x0BA28F10>
ID02 right mouse clicked
<guiMain.ProjectSelectButton object at 0x0BA28F10>
ID02 right mouse clicked
<guiMain.ProjectSelectButton object at 0x0BA22C00>
ID03 right mouse clicked
<guiMain.ProjectSelectButton object at 0x0BA22C00>
ID03 right mouse clicked

当我按下 ID 01 的按钮时我想要什么:

<guiMain.ProjectSelectButton object at 0x0BA34260>
ID01 right mouse clicked

问题

如何创建多个按钮,按下它们时将调用单个函数?

最佳答案

Programming Guide » Input management » Touch events

By default, touch events are dispatched to all currently displayed widgets. This means widgets receive the touch event whether it occurs within their physical area or not.

In order to provide the maximum flexibility, Kivy dispatches the events to all the widgets and lets them decide how to react to them. If you only want to respond to touch events inside the widget, you simply check.

解决方案

click_on_button方法中使用self.collide_point方法。当它碰撞时,你应该只按下一个按钮。详情请引用我的例子。

片段

class ProjectSelectButton(Button):
    def click_on_button(self, instance, touch, *args):
        print(instance)
        if self.collide_point(*touch.pos):
            if touch.button == 'right':
                print(self.id, "right mouse clicked")
            elif touch.buttom == 'left':
                print(self.id, "left mouse clicked")
            return True
        return super(ProjectSelectButton, self).on_touch_down(touch)

示例

main.py
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button


class CreateButton(Button):

    def on_touch_down(self, touch):
        if self.collide_point(*touch.pos):
            if touch.button == "right":
                print(self.id, "right mouse clicked")
            elif touch.button == "left":
                print(self.id, "left mouse clicked")
            else:
                print(self.id)
            return True
        return super(CreateButton, self).on_touch_down(touch)


class OnTouchDownDemo(GridLayout):

    def __init__(self, **kwargs):
        super(OnTouchDownDemo, self).__init__(**kwargs)
        self.build_board()

    def build_board(self):
        # make 9 buttons in a grid
        for i in range(0, 9):
            button = CreateButton(id=str(i))
            self.add_widget(button)


class OnTouchDownApp(App):

    def build(self):
        return OnTouchDownDemo()


if __name__ == '__main__':
    OnTouchDownApp().run()

ontouchdown.kv

#:kivy 1.10.0

<CreateButton>:
    font_size: 50
    on_touch_down: self.on_touch_down

<OnTouchDownDemo>:
    rows: 3
    cols: 3
    row_force_default: True
    row_default_height: 150
    col_force_default: True
    col_default_width: 150
    padding: [10]
    spacing: [10]

关于python - 将一个函数绑定(bind)到kivy中的多个动态创建的按钮?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45934429/

相关文章:

python - += 与 =+ 在 timedelta 中

python - Git 子模块在 python 项目中使用后会引发导入错误

python - 如何将这些数据转换为逻辑回归?

events - 仅在一列中使用 onEdit

python - _event.cpython-310-x86_64-linux-gnu.so : undefined symbol: _PyGen_Send 导入错误

c# - windows上的tcp服务器c#,tcp客户端python raspberry pi

java - 将值从 JTextField 传递到 ActionListener

javascript - AlloyUI Scheduler - 从数据库加载后添加自定义属性

python - 在kivy中预加载声音

python - Kivy Python 中的弹出窗口不会被解雇超过一次