Kivy多点触控应用崩溃:BindTexture对象无pos属性问题排查
解决Kivy多点触控应用触摸时崩溃的问题
问题原因
报错AttributeError: 'kivy.graphics.context_instructions.BindTexture' object has no attribute 'pos'的根源在于,你通过canvas.get_group()获取指令列表时,列表里的元素顺序并非你预期的「Color → Ellipse」。Kivy会在绘制过程中自动插入BindTexture指令,导致你用索引[1]取到的不是Ellipse对象,而是这个内部指令,自然没有pos属性。
解决方案
不要依赖指令列表的索引位置来获取你创建的图形元素,而是在初始化触摸点时直接保存Color和Ellipse对象的引用,后续更新时直接操作这些引用即可。
修改后的完整代码
import kivy from kivy.app import App from kivy.uix.widget import Widget from kivy.graphics import Color, Ellipse class TouchTracker(Widget): def __init__(self, **kwargs): super().__init__(**kwargs) # 用字典存储每个触摸点对应的Color和Ellipse对象 self.touch_objects = {} def on_touch_down(self, touch): with self.canvas: color = Color(0.5, 0.5, 0.5, mode='hsv', group=str(touch.uid)) d = 30 ellipse = Ellipse(pos=(touch.x - d / 2, touch.y - d / 2), size=(d, d), group=str(touch.uid)) # 保存当前触摸点的图形对象引用 self.touch_objects[touch.uid] = (color, ellipse) def on_touch_move(self, touch): # 从字典中取出当前触摸点对应的图形对象 color, ellipse = self.touch_objects.get(touch.uid, (None, None)) if color and ellipse: # 更新颜色和椭圆位置 color.hsv = (0.5, 0.5, 0.5) ellipse.pos = (touch.x - 15, touch.y - 15) def on_touch_up(self, touch): # 移除触摸点对应的图形元素并清理字典 color, ellipse = self.touch_objects.pop(touch.uid, (None, None)) if color: self.canvas.remove(color) if ellipse: self.canvas.remove(ellipse) class WindowApp(App): def build(self): return TouchTracker() WindowApp().run()
关键改动说明
- 新增
self.touch_objects字典,专门存储每个触摸ID对应的Color和Ellipse对象,避免依赖canvas指令列表的索引 on_touch_down中创建Color和Ellipse后,直接将它们存入字典,确保后续能准确获取on_touch_move通过触摸ID直接从字典取对象,判断存在后再更新属性,避免空引用错误on_touch_up从字典中取出对象并移除,同时删除字典中的记录,避免内存残留
内容的提问来源于stack exchange,提问作者InfernisVox
相关产品推荐
相关产品推荐

