What is the correct Qt idiom for exposing signals/slots of contained widgets?
Suppose I have a MyWidget
which contains a MySubWidget
, e.g. a custom widget that contains a text field or something. I want other classes to be able to connect to signals and slots exposed by the contained MySubWidget
insta开发者_如何学编程nce. Is the conventional way to do this:
- Expose a pointer to the
MySubWidget
instance through asubWidget()
method inMyWidget
- Duplicate the signals and slots of
MySubWidget
in theMyWidget
class and write "forwarding" code - Something else?
Choice 1 seems like the least code, but it also sort of breaks encapsulation, since now other classes know what the contained widgets of MyWidget
are and might become dependent on their functionality.
Choice 2 seems like it keeps encapsulation, but it's a lot of seemingly redundant and potentially convoluted code that kind of messes up the elegance of the whole signals and slots system.
What is normally done in this situation?
If you look at Qt's own code they prefer option 2.
For example, look at QTabWidget and QTabBar. They share a number of signals and slots, yet QTabWidget hides the fact that it uses a QTabBar (well, sorta... QTabWidget::tabBar()
obviously breaks this even though it's protected).
Although this will result in more code, I think it's worth it for the encapsulation.
Don't forget that you can connect signals to signals like so:
connect(mySubWidget, SIGNAL(internalSignal(int)), this, SIGNAL(externalSignal(int)));
Which will make MyWidget
emit externalSignal(int)
when MySubWidget
emits internalSignal(int)
. This helps with the signal side of things at least. I don't know of any easy way to do the same for slots, unfortunately.
I wouldn't worry about encapsulation of signals and slots, presumably only one thing is doing the connecting, so what's the harm in it knowing about some subclasses? If you are working on a larger team preventing abuse of the subWidget()
method is a concern but you could do that with the friend keyword or whatever...
You could expose a base class of MySubWidget that contains less functionality.
精彩评论