There are a few ways of dealing with this in Qt.
Idioms
Use multiple views with one underlying model. This handles propagation of changes to multiple view controls automatically and you don't need to do anything extra. You can use
QDataWidgetMapper
to link "plain old" widgets to the data elements in a model. I'd say that this should be the preferred way of doing things. Having an underlying model for all of your UI is a step in the direction of good software design anyway.When propagating changes between data models, implement both a
DisplayRole
and anEditRole
. The views will nominally modify the models using one of the roles (say, theEditRole
), while you can, programmatically, modify the models using the other role (say, theDisplayRole
). You handle thedataChanged
signals from the model in your own slot, properly dealing with the roles, and callsetData
on the other models with the other role. This prevents the loops.For controls that are not
QAbstractItemView
s, implement two signals: one emitted on any change, another one emitted only on changes based on keyboard/mouse input. This is the interface exposed byQAbstractButton
, for example: thetoggled(bool)
signal is the former, theclicked()
is the latter. You then only connect to the input-based signals.Your own code must propagate programmatic changes to all the interlinked controls, since changing one control from your code won't modify the others. This should not be a problem, since well designed code should encapsulate the implementation details of UI controls from rest of the code. Your dialog/window class will thus expose its properties in a way that's not coupled to the number of controls showing a particular property.
Hackish Let's-Hope-They-Won't-Become Idioms
Use a flag inhibiting signal emission (Bartosz's answer).
Break the signal/slot connections for the duration of the change (Bartosz's answer).
Use
QObject::blockSignals()
.