我正在尝试为我在python和pygame中创建的绘图程序创建一个撤消功能。我决定在用户每次更改后复制画布并将该副本添加到列表中。如果用户按下撤消按钮,则先前的图像将被加载到画布上。追加函数是否适用于这种情况(我在下面的代码中有它)?我只是想知道如何完成。这是一种有效的方法还是有更好的方法来做到这一点?
我也想知道“canvasFrame = canvas.copy()”的位置是否正确放置在这里(这是我的画笔工具。是否应该在我的所有计算之后放置canvas.copy()? ):
if mb[0] == 1 and canvas.collidepoint(mx,my):
screen.set_clip(canvas)
canvasFrame = canvas.copy()
frames.append(canvasFrame)
if tool == "brush":
x=mx-omx
y=my-omy
d = int(((x)**2+(y)**2)**0.5)
if d == 0:
d = 1
for i in range(int(d)):
dx = int(omx+i/d*x)
dy = int(omy+i/d*y)
draw.circle(screen,(c),(dx,dy),sz)
screen.set_clip(None)
基本上,我想知道的是如何在列表中设置最大份数(我假设使用MAX函数,但我不确定如何将它用于列表)以及我将如何将以前的画布图像加载到画布上。我花了很多时间搜索有关此问题的信息,但到目前为止还没有成功。任何帮助表示赞赏。谢谢。
我对python很新,对python中可以使用的更高级的函数没有多少经验,所以如果这个方法听起来不必要复杂,可能是因为我没有很多函数可以合作。
答案 0 :(得分:2)
我个人不会保存整个画布的副本,我会存储事件,例如将这样的事情附加到日志history.append( 4, 2, (128, 128, 128)
4,2
将是X / Y co在用户绘画/改变拼贴/像素颜色的地方,(128, 128, 128)
将是拼贴的旧颜色。因此,当您使用撤消功能时,您将要使程序转到列表history[len(history)-1]
中的最后一项,并将X / Y处的颜色替换为(128, 128, 128)
(历史记录[len(history)-1 ] [2])
喜欢这个
BLACK = (0, 0, 0)
current_color = None
#global
history = []
#global
...
def draw(event):
global history, canvas
#when a tile gets painted on
X=event.pos[0]
Y=event.pos[1]
history.append(X,Y,canvas[X][Y])
canvas[X][Y] = current_color
def undo():
global history, canvas
X = history[len(history)-1][0]
Y = history[len(history)-1][1]
color = history[len(history)-1][2]
canvas[X][Y] = color
history.pop(len(history)-1)
这样你使用的ram就少了很多,所以你可以存储更多的事件。
答案 1 :(得分:0)
如果您计划拥有最多历史记录条目,我会选择collections.deque
而不是列表。
使用双端队列,您可以指定最大条目数。如果条目附加到列表的一端并且双端队列已满,则从对端删除相应数量的条目。
from collections import deque
max_steps = 3
history = deque([1, 2, 3], maxlen=max_steps)
print history # deque([1, 2, 3], maxlen=3)
history.append(4)
print history # deque([2, 3, 4], maxlen=3)
history.extend([5, 6])
print history # deque([4, 5, 6], maxlen=3)