在Python中进行撤消

发布于 2024-08-17 07:31:03 字数 405 浏览 6 评论 0原文

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

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

希望我的想法很清楚,

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

first of all .. sorry if my english was bad. its my 3rd language

im working on a paint software that draw over images and save them again ( for commenting propose )
i use pile and wxpython.
but im still having problems with some features ..
what is the ideal way to make the undo option ?
another question .. when the user scale the picture ( by enlarging the drawing frame)
the lines doesn't scale . how do i make that happen .

i got rid of all those problems by saving temporary images to the hard disk whenever the user finishes a line and assign that new picture ( the old one with a line on it) to the frame .
undo and redo will is done by switching between those images ...
so when user scale image the line will scale too . but that is bad since it takes a lot of HDD space ( when you draw 1000 lines ) and its slow because it assigns a new image every time a user draw a line

hope my idea is clear

does anyone have a better solution ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

中性美 2024-08-24 07:31:03

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

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

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

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

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

The canonical strategy is to use the Command pattern. You'll represent the things you can do as Command objects, and each object is placed on a stack. The state of the application is then defined by an initial state plus everything that the stack has. Thus, the "undo" operation is then just popping the top stack item and reapplying the remaining items to the initial state.

In practice, sometimes it's expensive to keep applying those operations to the initial state to generate the current state. For example, this might be true with something like a complex series of image adjustments, like you might find in Photoshop. In cases like that, it's common to keep an alternating state-stack series in memory:

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

Each stack_i holds commands until it exceeds some pre-set complexity (e.g., the commands exceed computational cost X) or ordinal (e.g. the stack holds X or more commands) limit. At that point, a new intermediate state object state_i+1 is created to encapsulate the state, and a new, empty stack stack_i+1 is created to hold new commands.

In this way, you only have to apply a small sequence of commands to the last snapshotted state to get the current state. This comes at the expense of memorizing entire states, which may not be feasible for very large applications, but you can choose to snapshot only a set of the state to optimize.

柠檬色的秋千 2024-08-24 07:31:03

另外,请记住,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)

Also, keep in mind that Python's functions are first-class objects, which can make implementing the Command pattern very smooth:

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)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文