<html><head><style>body{font-family:Helvetica,Arial;font-size:13px}</style></head><body><div style="font-family:Helvetica,Arial;font-size:13px">Hi,</div><div style="font-family:Helvetica,Arial;font-size:13px"><br></div><div style="font-family:Helvetica,Arial;font-size:13px">consider this scenario:</div><div style="font-family:Helvetica,Arial;font-size:13px"><br></div><div style="font-family:Helvetica,Arial;font-size:13px">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:</div><div style="font-family:Helvetica,Arial;font-size:13px"><br></div><div style="font-family:Helvetica,Arial;font-size:13px">QML Engine <—> Proxy QObject <—> QObject model [worker QThread]</div><div style="font-family:Helvetica,Arial;font-size:13px"><br></div><div style="font-family:Helvetica,Arial;font-size:13px"><br></div><div style="font-family:Helvetica,Arial;font-size:13px">Obviously the UI should react to changes in the model, and the model should be updated by UI.</div><div style="font-family:Helvetica,Arial;font-size:13px"><br></div><div style="font-family:Helvetica,Arial;font-size:13px">For simplicity, assume the model is a real number, and the UI is a slider to change this value.</div><div style="font-family:Helvetica,Arial;font-size:13px"><br></div><div style="font-family:Helvetica,Arial;font-size:13px">>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.</div><div style="font-family:Helvetica,Arial;font-size:13px"><br></div><div style="font-family:Helvetica,Arial;font-size:13px">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.</div><div style="font-family:Helvetica,Arial;font-size:13px">Similar thing would happen if directly changing the value on the model.</div><div style="font-family:Helvetica,Arial;font-size:13px"><br></div><div style="font-family:Helvetica,Arial;font-size:13px">So far so good… well, that’s what I naïvely thought before hitting this problem:</div><div style="font-family:Helvetica,Arial;font-size:13px"><br></div><div style="font-family:Helvetica,Arial;font-size:13px">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.</div><div style="font-family:Helvetica,Arial;font-size:13px"><br></div><div style="font-family:Helvetica,Arial;font-size:13px">Where is the flaw in my design?</div><div style="font-family:Helvetica,Arial;font-size:13px">How can this problem be solved in a way that every Qt engineer could say “yes, that’s how it should be done”? :-)</div><div style="font-family:Helvetica,Arial;font-size:13px"><br></div><div style="font-family:Helvetica,Arial;font-size:13px">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.</div><div style="font-family:Helvetica,Arial;font-size:13px"><br></div><div style="font-family:Helvetica,Arial;font-size:13px">[*]: see "QQmlEngine: Illegal attempt to connect to ... that is in a different thread than the QML engine” and suggested solutions to it.</div><div style="font-family:Helvetica,Arial;font-size:13px"><br></div><div style="font-family:Helvetica,Arial;font-size:13px"><br></div><div style="font-family:Helvetica,Arial;font-size:13px">Best regards,</div><div style="font-family:Helvetica,Arial;font-size:13px">Federico Ferri</div></body></html>