You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python文件中为Kivy按钮绑定带*args的回调函数

问题原因

你的Python代码存在3个核心错误,导致逻辑无法正常运行:

  • 重写MainWidget的__init__方法时,没有调用父类FloatLayout的初始化方法,也没有将创建的按钮添加到控件树中,按钮本身不会被渲染显示
  • bind方法用法不符合Kivy语法规则:绑定事件需要明确指定事件名作为关键字参数,直接传入回调的写法是无效的
  • 直接绑定on_touch_down事件时,没有做触摸点碰撞检测,会导致点击屏幕任意位置都会触发回调,和kv中写在Button节点内的事件触发逻辑不一致
修正后的代码

main.py

from kivy.config import Config
Config.set('input', 'mouse', 'mouse,disable_multitouch')

from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.button import Button
from kivy.uix.bubble import Bubble

class MainWidget(FloatLayout):
    clicked = False
    def __init__(self, **kwargs):
        # 必须优先调用父类初始化方法
        super().__init__(**kwargs)
        b = Button(text="A")
        # 正确绑定按钮的触摸按下事件
        b.bind(on_touch_down=self.onpressed)
        # 将按钮添加到当前控件中
        self.add_widget(b)
        
    def onpressed(self, widget, touch):
        # 过滤非按钮区域的触摸事件,和kv内写事件的行为保持一致
        if not widget.collide_point(*touch.pos):
            return False
        if touch.button == 'left':
            print("LEFT")
            if self.clicked:
                self.remove_widget(self.ccp)
                self.clicked = False
        elif touch.button == 'right':
            print("RIGHT")
            if self.clicked:
                self.remove_widget(self.ccp)
            self.ccp = CutCopyPaste()
            self.add_widget(self.ccp)
            self.clicked = True
        return True

class CutCopyPaste(Bubble):
    pass

class RightClickApp(App):
    pass

if __name__ == "__main__":
    RightClickApp().run()

rightclick.kv

kv文件无需修改,保持原有内容即可:

MainWidget:

<MainWidget>:
    #Button:
    #    text: "A"
    #    on_touch_down: root.onpressed(*args)

<CutCopyPaste>:
    size_hint: (None, None)
    size: (160, 160)
    pos_hint: {'center_x': .5, 'y': .6}
    BubbleButton:
        text: 'Cut'
    BubbleButton:
        text: 'Copy'
    BubbleButton:
        text: 'Paste'
补充说明

如果不需要区分鼠标左右键,优先使用按钮自带的on_press/on_release事件,不需要手动处理碰撞检测,写法更简洁。当前场景需要识别右键操作,所以用on_touch_down加碰撞检测的写法是合理的。

内容的提问来源于stack exchange,提问作者GalaxyGamerYT

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 06:30:46