Al escribir GUI, con frecuencia me he encontrado con el siguiente problema: Supongamos que tiene un modelo y un controlador. El controlador tiene un widget W
que se utiliza para mostrar una propiedad X
del modelo.Ciclos de evento de interrupción en GUI
Como el modelo puede cambiarse desde el exterior del controlador (puede haber otros controladores que utilicen el mismo modelo, operaciones de deshacer, etc.), el controlador escucha los cambios en el modelo. El controlador también escucha los eventos en el widget W
y actualiza la propiedad X
en consecuencia.
Ahora, ocurre lo siguiente:
- se cambia el valor en
W
- se genera un evento, el controlador en el controlador se invoca
- el controlador establece el nuevo valor para
X
en el modelo - m Odel emite eventos porque se ha cambiado
- la controlador recibe un evento de cambio a partir del modelo
- el controladorobtiene el valor de
X
y lo establece en el widget - Goto 1.
Hay varias soluciones posibles para ello:
- Modifique el controlador para establecer un indicador cuando se actualice el modelo, y no reaccione ante ningún evento del modelo si se establece este indicador.
- Desconectar el controlador de forma temporal (o dice el modelo de no enviar ningún evento para algún tiempo)
- congelación de las actualizaciones desde el widget
En el pasado, yo solía ir a la opción 1., porque es la cosa más simple. Tiene el inconveniente de saturar sus clases con banderas, pero los otros métodos también tienen sus inconvenientes.
Solo para el registro, he tenido este problema con varios kits de herramientas GUI, incluyendo GTK +, Qt y SWT, por lo que creo que es bastante agotadora.
¿Alguna de las mejores prácticas? ¿O la arquitectura que uso simplemente está mal?
@Shy: Esa es una solución para algunos casos, pero aún se obtiene una ronda de eventos superfluos si X
se cambia desde fuera del controlador (por ejemplo, cuando se usa el patrón de comando para deshacer/rehacer), porque el valor ha cambiado, W
se ha actualizado y activa un evento. Para evitar otra actualización (inútil) del modelo, el evento generado por el widget debe ser eliminado.
En otros casos, el modelo podría ser más complejo y un simple control de lo que exactamente ha cambiado podría no ser factible, por ej. una vista de árbol compleja.
Tengo este problema con los cuadros de lista en MFC todo el tiempo. –