[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