4

首先..对不起,如果我的英语不好。它是我的第三种语言
,我正在开发一个绘图软件,它可以绘制图像并再次保存它们(用于评论建议)
我使用 pile 和 wxpython。但我仍然对某些功能有问题..
进行撤消选项的理想方法是什么?
另一个问题..当用户缩放图片(通过放大绘图框)时,线条不会缩放。我如何做到这一点。

每当用户完成一行并将新图片(上面有一条线的旧图片)分配给框架时,我通过将临时图像保存到硬盘来解决所有这些问题。撤消和重做将通过在这些图像之间切换来完成......所以当用户缩放图像时,线条也会缩放。但这很糟糕,因为它占用大量硬盘空间(当您绘制 1000 条线时)并且速度很慢,因为每次用户绘制一条线时它都会分配一个新图像

希望我的想法很清楚

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

4

2 回答 2

13

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

在实践中,有时将这些操作应用于初始状态以生成当前状态的成本很高。例如,这可能适用于一系列复杂的图像调整,就像您可能在 Photoshop 中找到的那样。在这种情况下,在内存中保留交替的状态堆栈系列是很常见的:

+---------+
| state_0 |
+---------+       +---------+
| next   -------> | stack_0 |
+---------+       +---------+
                  | data    |       +---------+
                  | next   -------> | state_1 |
                  +---------+       +---------+
                                    | next   ----- ...
                                    +---------+

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

这样,您只需将一小部分命令应用于最后一个快照状态即可获得当前状态。这是以存储整个状态为代价的,这对于非常大的应用程序可能不可行,但您可以选择仅对一组状态进行快照以进行优化。

于 2010-01-05T13:58:23.930 回答
9

另外,请记住 Python 的函数是一流的对象,这可以使命令模式的实现非常顺利:

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)
于 2010-01-05T16:53:06.827 回答