отменить в питоне - PullRequest
       27

отменить в питоне

4 голосов
/ 05 января 2010

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

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

надеюсь, моя идея ясна

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

Ответы [ 2 ]

12 голосов
/ 05 января 2010

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

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

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

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

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

7 голосов
/ 05 января 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)
...