When writing GUIs, I've frequently come over the following problem: Assume you have a model and a controller. The controller has a widget W
that is used to show a property X
of the model.
Because the model might be changed from outside the controller (there might be other controllers using the same model, undo operations etc), the controller listens to changes on the model. The controller also listens to events on the widget W
and updates the property X
accordingly.
Now, the following happens:
W
is changedX
in the model
X
and sets it in the widgetThere are several possible solutions for that:
In the past, I usually went for option 1., because it's the simplest thing. It has the drawback of cluttering your classes with flags, but the other methods have their drawbacks, too.
Just for the record, I've had this problem with several GUI toolkits, including GTK+, Qt and SWT, so I think it's pretty toolkit-agnostic.
Any best practices? Or is the architecture I use simply wrong?
@Shy: That's a solution for some cases, but you still get a round of superfluous events if X
is changed from outside the controller (for instance, when using the command pattern for undo/redo), because then the value has changed, W
is updated and fires an event. In order to prevent another (useless) update to the model, the event generated by the widget has to be swallowed.
In other cases, the model might be more complex and a simple check on what exactly has changed might not be feasible, e.g. a complex tree view.
The standard QT way of dealing with this and also the one suggested in their very useful tutorial is to make the change to the value in the controller only if the new value is different from the current value.
This is way signals have the semantics of valueChanged()
see this tutorial
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With