[Qt-interest] connect()ing multiple buttons to a receiver

Oliver.Knoll at comit.ch Oliver.Knoll at comit.ch
Thu Jan 8 17:48:53 CET 2009


Brad Howes wrote on Thursday, January 08, 2009 4:50 PM:

> On Jan 8, 2009, at 3:17 AM, Oliver.Knoll at comit.ch wrote:
>
>> While this works in practice it is dangerous and for good reason the
>> Qt docs discourage you to use the sender() method:
>>
>> http://doc.trolltech.com/4.4/qobject.html#sender
>> "Warning: This function violates the object-oriented principle of
>> modularity. However, getting access to the sender might be useful
>> when many signals are connected to a single slot."
>
> Discourage? Their 'however' clause covers the very scenario that was
> brought up.

In fact, I can't think of any scenario other than having many signals connected to a single slot where the method sender() would be of any use (why would you bother to call sender() if you just had one sender anyway?).

So IMHO their "however" clause is somewhat misleading here and should rather read "If your slot is very private in a class and you can guarantee that only - and only those - signals from the given senders are connected to it, then this method might be of use."

>> Imagine what would happen if anyone would connect any *other*
>> object's signal (other than from a QButton!) to your slot: Your code
>> ...
> The code should have used qobject_cast<> or dynamic_cast<> followed
> by a NULL check. Nothing scrary.
>
>      QButton* b = dynamic_cast<QButton*>( sender() );
>      if ( b ) {
>          ...
>      }

So imagine your slot was public (or protected, i.e. accessible from unforeseen positions in your code). Now Jim Business thinks it would be a great idea to have a "Recent Files Quick Access Toolbar"(tm) and Joe Programmer would implement a QButtonGroup with buttons numbered 1 to 10. Each QButton would then be connected to your slot and... ups, why does nothing happen?

I totally agree that it would not be disatrous and Joe Programmer (hopefully) tests the code and would realise that it would fail. He then would go on and extend your code with another "else if (b instanceof QButton)"... until Jim Business would think it would be a great idea to invoke the Recent Files with the SuperKeys of his new 10 button mouse he just bought last Xmas... well, you get the idea ;)

Like this the application logic would spread over your code - not something you want in large projects!

> I use this idiom all the time for a "Recent File" menu that maintains
> a dynamic list of QAction items with file names/paths, all connected
> to just one openRecentFile() slot.

You could have used a QActionGroup for that. (But to my surprise the Qt 4 Designer also uses sender() in their slot now - that was different in the Qt 3 version ;)

Again: for quick'n'dirty code or code which is used just very "locally" in a large application it might be okay to use sender(). But I would refrain from using sender() if the slot was public or protected and you could never foretell what other code will call it (maybe in 2 years away from now...). Especially since there are Qt constructs (QSignalMapper, QButtonGroup, QActionGroup) which are specifically designed for these cases, including yours.


Cheers, Oliver
--
Oliver Knoll
Dipl. Informatik-Ing. ETH
COMIT AG - ++41 79 520 95 22




More information about the Qt-interest-old mailing list