如何在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
相关产品推荐
相关产品推荐

