I am working on a python scripted slicelet where I instantiate/modify several Markups planes and vtk cubes based on several QSpinBox values (volume rendering is active). The process on the signal onValueChanged begins to be long, and I observe side effects: double increment of the QSpinBox when I click a single time on the upper arrow, for instance.
To speed up the process:
- I disable rendering during process and resume it afterwards.
- I modify markups in batch using StartModified() and EndModifed()
Still, with these optimizations, I have sometimes the double QSpinBox increment. I would say the best way to definitely solve this problem is to parameter all the Markups in a separate thread, so that the slot function runs very fast (which is probably the best thing to do).
But, I am in python… and I cannot find a proper way to do it… Would you have any advice or example I could adapt?
onValueChanged slot you should be simply modifying the state of mrml nodes and this will trigger
requestRender on any of the views where those are displayed. The views compress these renders automatically and will only display periodically to maintain interactivity. There shouldn’t be any double increment in this scenario. I suggest avoiding the idea of threads and work on getting the event mechanism to work smoothly. Perhaps you need to profile the computation to see where time is being spent.
I observed double-step of the spinbox in completely unrelated, different use cases. Maybe the slow updates make it more visible. It would be nice if someone could investigate and fix it.
Volume rendering is normally very fast if you use the GPU volume rendering mode. This, combined with event compression should make all the renderings fluid. Maybe somewhere there is a force render call in the loop (that does not request a call but immediately renders).
You may also try pauseRender/resume Render to speed up updates (that prevents even force render calls to take effect).
Hi Steve, Andras
After modified event compression, things were visibly better, but still at some point where many markups are handled, double increment happen. We can find usefull info here [QTBUG-14259] QSpinBox increments value multiple times on single mouse click when signal handlers are long-running - Qt Bug Tracker. It seems that an internal timer of about 100ms trigger multiple signals if the slot function is longer than that. I could subclass QSpinBox and change this parameter but it is not possible as far as I know in python.
No need to subclass QSpinBox. You can always just start a single-shot timer from the QSpinBox callback function and do the update when that timer elapses. See for example self.databaseRefreshRequestTimer in the DICOM browser.
Well, at first I wanted to avoid it, but it effectively solves the issue… Deal.
Thanks both of you