我如何在kivy中删除画布上的线条

2024-06-28 11:01:15 发布

您现在位置:Python中文网/ 问答频道 /正文

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

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 = []

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


Tags: selfifondefwidth按钮pointdown
2条回答

尝试将它们放入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()

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

相关问题 更多 >