[Qt-interest] Howto: multiple emissions of signal cause one single slot execution.

Sean Harmer sean.harmer at maps-technology.com
Fri Jun 11 14:22:02 CEST 2010


Hi,

On Friday 11 June 2010 13:04:16 Davor J. wrote:
> Suppose you have a signal "raise()" and a slot "raiseHand()". Suppose that
> several objects can emit the "raise()" signal, simultaneously, during their
> function executions, etc... Suppose now that during execution the "raise()"
> signal is emitted several times in a continuous execution while the event
> loop is non-idle. Suppose all this happens in one main thread.
> 
> Now the question: How would you execute "raiseHand()" only once in such a
> scenario? (In other words: You don't want to raise the hand on every single
> yell, but as a confirmation on all the yells, given a certain happening.)
> 
> I was thinking on something as QTimer::singleshot(0, this,
> SLOT(raiseHand())), as it executes "raiseHand()" when the event loop
> becomes idle. But still, it would execute as many times as "raise()" is
> called.
> 
> An other option is to use a timer that resets itself after some 5-10msec,
> and only triggers the "raiseHand()" if it is allowed to timeout. But this
> seems a workaround and isn't pretty. Best would be to execute it only once
> when the event loop is idle.
> 
> Has Qt framework support for this? Or has anyone better suggestions?

If all of the above happens in the main thread and you are using 
Qt::DirectConnection's then the raiseHand() slot will be called immediately 
when you emit the raise() signal each time.

One possible solution is to have a bool m_alreadyRaisedHand member in the 
class that has the raiseHand() slot and check this at the very start of the 
slot. If the variable is true, simply return immediately. The variable should 
be set to true when the slot is successfully executed.

You will obviously need a way to reset the state of that variable ready for 
the next time you do your processing - perhaps a lowerHand() slot could be 
added that simply resets the member variable back to false.

If you wish to completely avoid the raiseHand() slot being called at all on 
subsequent raise() signals then another possibility is to call disconnect() to 
remove the connection. Again, you would have to reinstate that at the start of 
the next time through your processing calls. It is best to do this from 
outside the class that has the raiseHand() slot as it should not know anything 
about the source of the signals that trigger the slot - ie maintain the loose 
coupling of signals/slots.

Cheers,

Sean



More information about the Qt-interest-old mailing list