Kivy Python中添加DrawingWidget至现有代码后无法绘图的问题
问题解决:Kivy中DrawingWidget嵌套后无法绘图的问题
问题根源
你的DrawingWidget无法绘图的核心原因是KV文件中给DrawingWidget添加了多余的BoxLayout:这个BoxLayout会覆盖在DrawingWidget的画布之上,拦截所有触摸事件,导致on_touch_down和on_touch_move方法无法触发。同时这个BoxLayout设置了固定高度50,也限制了绘图区域的有效大小。
另外,MyGridLayout中承载DrawingWidget的GridLayout没有设置合适的尺寸参数,导致绘图区域被压缩,进一步影响交互。
修改方案
1. 修正KV文件
移除DrawingWidget内部的BoxLayout,并调整布局参数让绘图区域有足够空间:
<MyGridLayout>: ScrollView: size: root.width, root.height GridLayout: cols:1 padding:9,9,9,9 size_hint_y: None height: self.minimum_height GridLayout: cols:3 size_hint_y:.5 height: 100 Label: Button: text:'Enter Activity' on_press:root.sendmatt() size_hint_x:3 size_hint_y:1 Label: GridLayout: cols:1 size_hint_y: 2 height: 400 DrawingWidget: size_hint: 1, 1 <DrawingWidget>: # 移除多余的BoxLayout,保留画布逻辑即可
2. 调整Python代码逻辑
补充按钮点击方法并优化触摸事件处理逻辑:
class MyGridLayout(Widget): def __init__(self, **kwargs): super(MyGridLayout, self).__init__(**kwargs) def sendmatt(self): print("Button pressed") class DrawingWidget(Widget): def __init__(self, **kwargs): super(DrawingWidget, self).__init__(**kwargs) with self.canvas: Color(1, 1, 1, 1) self.rect = Rectangle(size=self.size, pos=self.pos) self.bind(pos=self.update_rectangle, size=self.update_rectangle) def update_rectangle(self, instance, value): self.rect.pos = self.pos self.rect.size = self.size def on_touch_down(self, touch): if not self.collide_point(*touch.pos): return False with self.canvas: Color(0, 0, 0, 1) self.line = Line(points=[touch.pos[0], touch.pos[1]], width=2) return True def on_touch_move(self, touch): if not self.collide_point(*touch.pos): return False if hasattr(self, 'line'): self.line.points.extend([touch.pos[0], touch.pos[1]]) return True def on_touch_up(self, touch): if not self.collide_point(*touch.pos): return False return True class funcswspinnerall(App): def build(self): return MyGridLayout() if __name__ == '__main__': funcswspinnerall().run()
关键说明
- 移除
DrawingWidget内的BoxLayout后,触摸事件能直接传递到DrawingWidget的触摸处理方法,确保绘图逻辑正常触发。 - 设置
DrawingWidget的size_hint:1,1让它占满父容器,保证绘图区域足够大。 - 在触摸处理方法中返回
True,明确标记事件已被处理,避免事件继续向下传递导致干扰。
内容的提问来源于stack exchange,提问作者Michael McCone
相关产品推荐
相关产品推荐

