decoupling complex GUIs with signals/slots

eliben wrote:

  
I've had a more serious look at pubsub, and either I misunderstand it or I
see a problem with it. In pubsub, the publishing of messages is extremely
"global". All the objects in the application that have subscribed to some
message will receive it, _no matter who sent it_ - and herein is the
problem.

Consider a frame with two widgets of the same type. The widgets have
messages they can send to notify the world of something (true to the MVC
paradigm). The message is of course the same - let's call it "readmeagain".
However, the top frame needs to do something different with the messages
from each widget (for example, it has to update a different status log for
each of the widgets). It has subscribed to "readmeagain" and will receive it
no matter who sent it, all into the same handler. How does it know which
widget sent it, without forcing the sending widget to incorporate some
identification into the data attached to the message (which is quite
contrary to true MVC) ?

In Qt's signals/slots this is easy since the connection of signals to slots
is much more "personal", from a specific object's signal to a specific
object's slot, and not bazaar-like, as in pubsub.

So, is this a real problem or did I miss something ?

I think you may have missed something. Pubsub allows for much greater complexity than just sending a "message". You can use it in a primitive string-as-message way like you described, and I often do for simple applications. However, there is the whole concept of topics and specificity, which allows you to scale up nicely. So you can do something like sendMessage(('widget1', 'needsUpdate'), [data]). Now you can subscribe to all widget1 events by doing a subscribe('widget1'), or just for the update, subscribe(('widget1', 'needsUpdate')). Subscribing to a message will cause responses from anything that matches or is MORE specific (has more subtopics), but not LESS specific. So for example subscribing to ('widget1', 'needsUpdate') will get you a message from ('widget1', 'needsUpdate', 'urgent') but not just 'widget1' and not ('widget1', 'somethingElse'). This might explain it better: wxPython API Documentation — wxPython Phoenix 4.2.2 documentation.

This might allow it to be more of what you are looking for. Then again it may not. The point here I think is to be pythonic and do the equivalent of duck-typing. It isn't important what specific object or type of object sent the message (that's why it doesn't send along itself, although you could through the data), but whether the message is something the subscriber understands. Through the use of topics you can accomplish some pretty nice event handling, without having to sending the identification in the data, which you rightfully seek to avoid, so you can listen for exactly what you want and not have to check the data to see if it matches.

- Mike