При написании GUI я часто сталкиваюсь со следующей проблемой: Предположим, у вас есть модель и контроллер. В контроллере есть виджет W
, который используется для отображения свойства X
модели.
Поскольку модель может быть изменена извне контроллера (могут быть другие контроллеры, использующие ту же модель, отменяющие операции и т. Д.), Контроллер прослушивает изменения в модели. Контроллер также прослушивает события в виджете W
и обновляет свойство X
соответственно.
Теперь происходит следующее:
- значение в
W
изменено
- событие генерируется, вызывается обработчик в контроллере
- контроллер устанавливает новое значение для
X
в модели
- модель генерирует события, потому что она была изменена
- контроллер получает событие изменения от модели
- контроллер получает значение
X
и устанавливает его в виджете
- Перейти к 1.
Для этого есть несколько возможных решений:
- Измените контроллер для установки флага при обновлении модели и не реагируйте на какие-либо события из модели, если этот флаг установлен.
- Временно отключите контроллер (или попросите модель не отправлять какие-либо события в течение некоторого времени)
- заморозить любые обновления из виджета
В прошлом я обычно выбирал вариант 1. потому что это самая простая вещь. У него есть недостаток - загромождать ваши классы флагами, но у других методов тоже есть свои недостатки.
Просто для справки, у меня была эта проблема с несколькими GUI-инструментариями, включая GTK +, Qt и SWT, поэтому я думаю, что она довольно независима от инструментария.
Есть лучшие практики? Или архитектура, которую я использую, просто неверна?
@ Shy: Это решение для некоторых случаев, но вы все равно получаете раунд избыточных событий, если X
изменяется из-за пределов контроллера (например, при использовании шаблона команды для отмены / возврата), потому что значение изменилось, W
обновлено и вызывает событие. Чтобы предотвратить другое (бесполезное) обновление модели, событие, генерируемое виджетом, необходимо проглотить.
В других случаях модель может быть более сложной, и простая проверка того, что именно изменилось, может оказаться невозможной, например, сложный вид дерева.