Specifically in response to the return values, I haven't felt that Qt's signals and slot make a good back-and-forth mechanism. As the others have mentioned, they work very well in the observer pattern/role. If you think about it, there are potential problems with the return values... such as what happens when you have more than one slot connected to a signal, and they each return different values? The same problems occur in the SigC++ and Boost::Signals libraries, where each has a (different?) mechanism to deal with it, or at least figure out what you'd be getting.
If you really need a return value, there are two relatively nice ways I've found to manage it. The first is to use Qt's event mechanism to request data, then pass the requested data back as a response. Note that the events don't have a built-in way to do responses, so you would need extend QEvent to be able to handle this case. We actually do this a fair amount in the applications at my job. It works quite well for a threaded application, when you need the asynchronous mechanism. The drawback to this method is that the requestor needs to know about the object it is requesting data from (in order to send the event). The responding object doesn't need to know any more than the request and how to send back the response, which is usually encoded into the request. Note that this is almost the opposite of the observer pattern.
The second method is to pass a functor object to the object that needs to be able to request data. This works a lot better with a good abstract functor library that lets you encapsulate objects and functions, such as the aforementioned SigC++ or Boost::Signals. This also works well for situations where you want an immediate response -- you run the functor's operator, and it returns a value before you continue processing in the function. This also allows you to write an object similar to how you would with the signal/slot mechanism, where the object that needs the return value from the function (signal) doesn't need to know anything about where the functor (signal's connection) was made, or came from. It just runs the functor as necessary.