【问题标题】:How do I delete lines from the canvas in kivy如何从kivy的画布中删除线条
【发布时间】:2017-12-06 12:39:34
【问题描述】:

我正在创建一个简单的绘图应用程序,我想在其中添加一个撤消按钮。到目前为止,我尝试过的是:

class DrawScreen(Screen):
    r = NumericProperty(0)
    g = NumericProperty(0)
    b = NumericProperty(0)
    brush_width = NumericProperty(2)

    def on_touch_down(self, touch):
        self.slider = self.ids.slider
        if self.slider.collide_point(touch.x, touch.y):
            self.brush_width = self.slider.value
        else:
            self.undo = [touch.x, touch.y]
            with self.canvas.before:
                Color(self.r, self.g, self.b)
                touch.ud["line"] = Line(points=self.undo, width=self.brush_width)
        return super(DrawScreen, self).on_touch_down(touch)

    def on_touch_move(self, touch):
        if self.slider.collide_point(touch.x, touch.y):
            self.brush_width = self.slider.value
        else:
            try:
                self.undo += [touch.x, touch.y]
                touch.ud["line"].points = self.undo

            except:
                pass
        return super(DrawScreen, self).on_touch_move(touch)

    def color(self, r, g, b):
        self.r = r
        self.g = g
        self.b = b

    def undo_draw(self):
        self.undo = []

此撤消按钮会清除列表,但不会以任何方式影响画布,也不会删除任何行。解决此问题的适当方法是什么?

【问题讨论】:

    标签: python kivy kivy-language


    【解决方案1】:

    尝试将它们放入InstructionGroup,然后添加到canvas,然后只需使用canvas.remove(item) 从画布中删除该项目。

    如果您想重做,您可能需要保存这些项目。
    试试这个例子。我不得不替换on_touch_down,当我用鼠标垫移动光标时,它一直在创建指令,用孩子填充画布:

    from kivy.app import App
    from kivy.lang import Builder
    from kivy.graphics import Line, Color, InstructionGroup
    from kivy.uix.widget import Widget
    
    
    class MyWidget(Widget):
    
        undolist = []
        objects = []
        drawing = False
    
        def on_touch_up(self, touch):
            self.drawing = False
    
        def on_touch_move(self, touch):
            if self.drawing:
                self.points.append(touch.pos)
                self.obj.children[-1].points = self.points
            else:
                self.drawing = True
                self.points = [touch.pos]
                self.obj = InstructionGroup()
                self.obj.add(Color(1,0,0))
                self.obj.add(Line())
                self.objects.append(self.obj)
                self.canvas.add(self.obj)
    
    
        def undo(self):
            item = self.objects.pop(-1)
            self.undolist.append(item)
            self.canvas.remove(item)
    
        def redo(self):
            item = self.undolist.pop(-1)
            self.objects.append(item)
            self.canvas.add(item)
    
    
    KV = """
    
    BoxLayout:
        MyWidget:
            id: widget
        Button:
            text: "undo"
            on_release:
                widget.undo()
        Button:
            text: "redo"
            on_release:
                widget.redo()
    
    
    """
    
    
    class MyApp(App):
    
        def build(self):
            root = Builder.load_string(KV)
            return root
    
    MyApp().run()
    

    【讨论】:

    • @Baxorr 你很高兴。
    【解决方案2】:

    您可能仍然想知道为什么您的代码不起作用。原因是关键字参数points=self.undo 将复制对self.undo 表示的列表的引用。然后,当您的代码执行self.undo = [] 时,您将创建一个新的空列表,并告诉self.undo 指向它。但是self.undo 在此之前指向的原始列表仍然存在,points 仍然引用该列表。
    如果你不是self.undo = [],而是del self.undo[:],你可能会完成你想要的。

    【讨论】:

      猜你喜欢
      • 2016-07-05
      • 2021-10-07
      • 2014-06-30
      • 1970-01-01
      • 1970-01-01
      • 2023-03-19
      • 1970-01-01
      • 2011-12-18
      • 1970-01-01
      相关资源
      最近更新 更多