Hi, consider this scenario:
I have a Qt Quick application, and a C++ model which I need to have in a separate thread. Since it is not possible* to connect a QObject from another thread with the QML engine, I have also a proxy QObject living in the main thread, forwarding the signals and slots via other signal/slot connections. This can be sumarized in this diagram: QML Engine <—> Proxy QObject <—> QObject model [worker QThread] Obviously the UI should react to changes in the model, and the model should be updated by UI. For simplicity, assume the model is a real number, and the UI is a slider to change this value. >From what I can see, the mechanism for avoiding an infinite change loop adopted by QtQuick is to generate a valueChanged event (signal) if the value being set is different from the old value. So I implement this mechanism also on the C++ model side. So, for instance, if the slider’s value is 42, and i (programmatically) set it to 42, no change event happens; if I set it to 99, a valueChange will be emitted, which will also reach the model, set the model state to 99 as well; the latter will cause another valueChange to be emitted from C++ back to QML, but it will stop there, as the value is already 99. Similar thing would happen if directly changing the value on the model. So far so good… well, that’s what I naïvely thought before hitting this problem: Suppose we start again from 42. Dragging the slider will generate valueChanged(43), valueChanged(44), etc.. in a burst. Due to the queued connection across the QThread boundary, these changes will lag a bit. As soon as the model sees the valueChanged(43), will emit a similar signal back to the UI. But when that valueChanged(43) signal will reach the UI, due to the lag, the UI will be already in the 44 state, i.e. at the point where the dragging had stopped. So it will generate another valueChanged(43) towards the model, while a similar thing is happening also for the next signal in the queue (44), thus generating an infinite sequence of change signals. Where is the flaw in my design? How can this problem be solved in a way that every Qt engineer could say “yes, that’s how it should be done”? :-) Note: I would have preferred a lot if the proxy QObject was not needed, i.e. if the QML engine could make queued connections to a QObject living in another QThread. But that is not the cause of the problem, as with a queued connection (between QML engine and the C++ model in the worker thread), there still would be lag in signal/slot transport. [*]: see "QQmlEngine: Illegal attempt to connect to ... that is in a different thread than the QML engine” and suggested solutions to it. Best regards, Federico Ferri
_______________________________________________ Interest mailing list Interest@qt-project.org https://lists.qt-project.org/listinfo/interest