PDA

View Full Version : Queuing problem with signal and slots



montylee
22nd March 2009, 19:27
I have a custom signal of one class which is connected to a slot of a different class.
The signal is emitted upon click of a push button. Now, when the push button is clicked slowly, the slot is called properly. But if the push button is clicked rapidly, the slot is not called immediately for all clicks. The signal is emitted immediately but the corresponding slot calls are queued. Due to this the the GUI update i do in the slot is slow.

I tried using Qt::DirectConnection while connecting the signal to slot but it should be default i guess as i am not using any threads.

Is there any other way i can force the slot to be called immediately when the signal is fired?

montylee
22nd March 2009, 21:32
I think i found the reason why the slots are getting queued up.
When the push button is pressed rapidly, the slot is called, the slot performs some complex stuff which takes time. The slot is still performing the stuff when the next signal comes but the slot is not called again as the previous call to the slot is still executing, so it's queued up.

I don't know how to solve this problem. I can try calling the slots in a new thread for parallel execution but that wouldn't make sense since the next call to the slot should be executed only once the 1st call is over.

Hiker Hauk
23rd March 2009, 04:41
Maybe try to implement a command queue in the slot and all the slot function does is to queue the command and return. Start a working thread to execute the command queue.

But if it the operation is complex as your stated, and you keep clicking the button non-stop, chances are this command queue will eventually overflow.

Why not block and do not emit the signal if the previous computation is not finished yet?
You can also disable the button, if it is acceptable.

montylee
24th March 2009, 06:16
Actually it's a hardware button so it can't be disabled. I donno how to solve this for now. Maybe i need to simplify the code in the slot and make it fast. The slot code is not written by me so i need to go through it and see if i can make it fast.

Coises
20th November 2009, 06:11
A couple thoughts, maybe useful, maybe not...

I think what’s happening is not that the signal/slot is being queued, but that the button-press event itself is being held up in the GUI event queue. This would imply that any user interface action following a press of your button will be delayed until the slot code completes.

If experiment shows that this is true, then you might want either to perform the complex action in another thread, or to find safe points of interruption where you can either return to the event loop (first queuing an event that will start the next phase of the process) or call QCoreApplication::processEvents (if stacking other events on top of this process will work — this sounds simpler at first, but remember that all pending events will be processed before returning from QCoreApplication::processEvents to your process code!).

Suppose the user presses the button five times during the span of time it takes to complete the action of two presses. You will have to decide which is worse: either you ignore three button presses, or three actions commence after the user has stopped pressing the button. If the user will probably press the button some particular number of times (set in his or her mind before beginning to press the button), then it would be less annoying to do all the actions, when you can get to them; but if the user probably presses an undetermined number of times, until a desired result is observed, then it would be better to drop presses to which you can’t respond immediately.

You’ll need either a flag (set when beginning the process, cleared when it’s finished, and tested on each button press to determine whether to start a process or ignore the press) or a counter (incremented when the button is pressed, decremented when the process finishes, tested after increment to determine whether the process must be started, and tested after decrement to determine whether to repeat the process). If you use a counter and a separate thread, the counter must be protected against concurrent updates.