сделать отмену в питоне

прежде всего .. извините, если мой английский был плохим. это мой третий язык
я работаю над программой для рисования, которая рисует поверх изображений и сохраняет их снова (для комментариев предлагаю)
я использую ворс и wxpython. но у меня все еще есть проблемы с некоторыми функциями ..
каков идеальный способ сделать опцию отмены?
еще вопрос... когда пользователь масштабирует картинку (увеличивая рамку чертежа), линии не масштабируются. как мне это сделать .

я избавился от всех этих проблем, сохраняя временные изображения на жесткий диск всякий раз, когда пользователь заканчивает линию и назначает новое изображение (старое с линией на нем) кадру. отмена и повтор будут выполняться путем переключения между этими изображениями ... поэтому, когда пользователь масштабирует изображение, линия тоже будет масштабироваться. но это плохо, так как занимает много места на жестком диске (когда вы рисуете 1000 линий) и работает медленно, потому что назначает новое изображение каждый раз, когда пользователь рисует линию

надеюсь моя мысль ясна

у кого-нибудь есть лучшее решение?


person Moayyad Yaghi    schedule 05.01.2010    source источник
comment
какие? вы должны предоставить несколько примеров кода для каждого конкретного вопроса.   -  person danjarvis    schedule 05.01.2010
comment
мне нужны только идеи .. не решения кода   -  person Moayyad Yaghi    schedule 05.01.2010
comment
Хотя можно сопереживать тому, что ваш английский плохой, в будущем старайтесь избегать ввода заглавных букв, КАК ЭТО, избегайте использования нескольких вопросительных знаков, подобных этому ??? и пишите на полном английском (так что нет any1, пишите кому угодно). Это делает чтение поста более приятным (и все заглавные буквы считаются грубыми, так как кричат)   -  person blwy10    schedule 05.01.2010
comment
спасибо за это, и извините еще раз.   -  person Moayyad Yaghi    schedule 06.01.2010


Ответы (2)


Каноническая стратегия заключается в использовании шаблона команды. Вы будете представлять то, что вы можете делать, как объекты Command, и каждый объект помещается в стек. Затем состояние приложения определяется начальным состоянием и всем, что есть в стеке. Таким образом, операция «отменить» затем просто извлекает верхний элемент стека и повторно применяет оставшиеся элементы к исходному состоянию.

На практике иногда дорого продолжать применять эти операции к начальному состоянию для создания текущего состояния. Например, это может быть верно для чего-то вроде сложной серии корректировок изображения, как в Photoshop. В таких случаях принято хранить в памяти серию чередующихся стеков состояний:

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

Каждый stack_i содержит команды до тех пор, пока не превысит некоторую заранее установленную сложность (например, команды превышают вычислительную стоимость X) или порядковый (например, стек содержит X или более команд) лимит. В этот момент создается новый объект промежуточного состояния state_i+1 для инкапсуляции состояния, а также создается новый пустой стек stack_i+1 для хранения новых команд.

Таким образом, вам нужно всего лишь применить небольшую последовательность команд к последнему состоянию моментального снимка, чтобы получить текущее состояние. Это происходит за счет запоминания целых состояний, что может оказаться невозможным для очень больших приложений, но вы можете сделать снимок только набора состояний для оптимизации.

person John Feminella    schedule 05.01.2010

Кроме того, имейте в виду, что функции 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)
person Ned Batchelder    schedule 05.01.2010