在python中进行撤消

Moa*_*ghi 4 python wxpython image undo python-imaging-library

首先..抱歉,如果我的英语不好.它是我的第三语言
我正在使用绘制软件绘制图像并再次保存它们(用于评论建议)
我使用桩和wxpython.但我仍然遇到一些功能问题..
什么是做出撤销选项的理想方法?
另一个问题..当用户缩放图片时(通过放大绘图框),线条不会缩放.我该如何做到这一点.

每当用户完成一行并将新图片(旧图片上有一行)分配给框架时,我就可以通过将临时图像保存到硬盘来消除所有这些问题.undo和redo将通过在这些图像之间切换来完成...所以当用户缩放图像时,线条也会缩放.但这很糟糕,因为它需要大量的硬盘空间(当你绘制1000行时)并且它很慢,因为它每次用户画线时都会分配一个新的图像

希望我的想法很清楚

有没有人有更好的解决方案?

Joh*_*lla 12

规范策略是使用Command模式.您将表示可以作为Command对象执行的操作,并且每个对象都放在堆栈上.然后,应用程序的状态由初始状态加上堆栈具有的所有内容定义.因此,"撤销"操作然后只是弹出顶部堆栈项并将剩余项重新应用到初始状态.

实际上,有时将这些操作应用于初始状态以生成当前状态是昂贵的.例如,对于一系列复杂的图像调整,可能会出现这种情况,就像在Photoshop中找到的那样.在这种情况下,在内存中保持交替状态堆栈序列是很常见的:

+---------+
| state_0 |
+---------+       +---------+
| next   -------> | stack_0 |
+---------+       +---------+
                  | data    |       +---------+
                  | next   -------> | state_1 |
                  +---------+       +---------+
                                    | next   ----- ...
                                    +---------+
Run Code Online (Sandbox Code Playgroud)

每个stack_i保持命令直到它超过某些预设复杂度(例如,命令超过计算成本X)或序数(例如,堆栈保持X或更多命令)限制.此时,state_i+1将创建一个新的中间状态对象来封装状态,并stack_i+1创建一个新的空堆栈来保存新命令.

这样,您只需将一小段命令应用于上次快照状态即可获得当前状态.这是以记忆整个状态为代价的,这对于非常大的应用程序可能是不可行的,但是您可以选择仅对一组状态进行快照以进行优化.


Ned*_*der 7

另外,请记住Python的函数是第一类对象,这可以使Command模式非常流畅:

actions = []

def do_action1(arg1, arg2):
    # .. do the action ..

    # remember we did the action:
    actions.append(do_action1, (arg1, arg2))

def do_action2(arg1, arg2):
    # .. do the action ..
    actions.append(do_action2, (arg1, arg2))

def replay_actions():
    for fn, args in actions:
        fn(*args)
Run Code Online (Sandbox Code Playgroud)