[Qt-interest] Qt, C++ Namespaces, and Signals/Slots
Constantin Makshin
cmakshin at gmail.com
Fri Jun 25 21:20:47 CEST 2010
In my example ClassA and ClassB *are* derivatives of QObject, but SubClassA isn't. The only problem there is that connect() function doesn't use object types to check if signal and slot parameters are valid — its validation algorithms isn't much more complex than simple strcmp().
Your case is significantly more complicated and, in fact, impossible to implement simply because Qt can't track typedefs and renamed namespaces at run-time. If you look at SIGNAL() and SLOT() macro definitions in "QtCore/qobjectdefs.h" header file, you'll see that all they do is convert passed parameter into string and add "2" and "1" prefix, respectively.
So your call from example 1
connect(_a,SIGNAL(someSignal(X:someEnum)),_b,SLOT(someslot(myLocalEnum)));
is equal to
connect(_a,"2someSignal(X:someEnum)",_b,"1someslot(myLocalEnum)");
and since there's no way Qt can know (at run-time) that "myLocalEnum" is an alias to "X:someEnum", it won't be able to establish this connection.
The same thing is in example 2.
I'm sorry, but what you want to do is technically impossible.
On Friday 25 June 2010 17:54:45 BRM wrote:
> Well, to follow up (and that e-mail took a long time for some reason to reach the list so I couldn't follow up earlier) I had recently redirected some information output by qDebug to my program's internal log, and mistakenly was looking in the wrong place. Everything seemed to have worked, and I didn't see any statements about signals/slots not connecting so it seemed to be working; I was later looking at the logs for other things when I noticed it wasn't really working - I just wasn't exercising the relevant signals/slots at all any more so it didn't make a lick of difference in the program any way. So my original question is invalid.
>
> Either way, the below is very useful information; though I think it is rather obvious that sub-classes are not supported that way since they would have to be QObject derivatives in themselves and MOC doesn't like having subclasses derived from QObject defined like that (if I understand things correctly); so they would need their own headers/implementation files any way to be able to interact with signals/slots. I am strictly only dealing with namespaces; though that does lead me to another question now that I think about it - is MOC and Qt Signals/Slots smart enough to match a typedef'd version with its original? Or to follow namespace renaming?
>
> Example 1:
> namespace X {
> enum someEnum {...};
> }
> ...
> typedef X:someEnum myLocalEnum;
> ...
> connect(_a,SIGNAL(someSignal(X:someEnum)),_b,SLOT(someslot(myLocalEnum)));
>
>
> Example 2:
> namespace X {
> namespace Y {
> enum someEnum {...};
> }
> }
> ...
> namespace W = X:Y;
> ...
> connect(_a,SIGNAL(someSignal(X:Y:someEnum)),_b,SLOT(someslot(W:someEnum)));
>
>
> Ben
>
>
> ----- Original Message ----
> > From: Constantin Makshin <cmakshin at gmail.com>
> > To: Qt Interest <qt-interest at trolltech.com>
> > Sent: Thu, June 24, 2010 12:28:52 PM
> > Subject: Re: [Qt-interest] Qt, C++ Namespaces, and Signals/Slots
> >
> > Parameters of SIGNAL() and SLOT() macros must be exactly equal to corresponding
> > signal/slot declaration. So in your example the connect() statement should look
> > like this:
>
> connect(_a, SIGNAL(someSignal(X:Y:anEnum)), this,
> > SLOT(someSlot(X:Y:anEnum));
>
> And remember that Qt's meta object system
> > doesn't support nested types. For example:
>
> class
> > ClassA
> {
> public:
> class SubClassA
>
> > {
> ...
> };
>
>
> > ...
>
> signals:
> void someSignal (const
> > ClassA::SubClassA&); // <- !!!
> };
>
> class ClassB
> {
>
> > ...
>
> public slots:
> void someSlot (const
> > ClassA::SubClassA&);
> };
>
> Note that you have to write complete
> > parameter type specifier in someSignal() because if you write it as "void
> > someSignal(const SubClassA&);", it'll be correct from C++ point of view, but
> > any attempt to connect someSignal() and someSlot() will fail with "parameter
> > type mismatch" type of error. I had this problem during development of one of my
> > applications and would like to help you to avoid it. :)
>
> On Thursday 24
> > June 2010 19:19:21 BRM wrote:
> > I am moving around some definitions from a
> > Qt-only header set to a shared Qt and Standard C++ header sets.
> > In the
> > new header sets I am utilizing C++ namespaces. Updating everything seems to have
> > gone fine, but thus far I've only tested using MSVC.
> > Presently this just
> > applies for a series of enums, and a few structures as well; a number of these
> > get used in signals and slots.
> > Not every use of the types warrants the
> > implementation file having a using namespace for the namespace these are stored
> > in - and I will have multiple levels of namespaces.
> >
> > What I am
> > curious about is that in one case the function definitions for the signals/slots
> > included the namespaces;
> > however, I didn't put the namespaces in the
> > connect() statement - or the SIGNAL()/SLOT() sub-parts of it; yet, Qt seems to
> > have made the right connections, and allowed it.
> > I expected I would have
> > to update the SIGNAL()/SLOT() to have the namespace parts in it too. Presently I
> > have only noticed this for some standard C++ enums that I reference.
> > But
> > I am wondering if this is by design or some fluke - e.g. can I rely on this, or
> > should I really namespace the parameters?
> >
> > Where I have used
> > qRegisterMetaType<>() to register something I did add in the namespace
> > referencing, but I have not done that in all cases.
> >
> >
> > Example:
> >
> > namespace X {
> > namespace Y
> > {
> > enum anEnum {
> >
> > anEnumValue1=0,
> >
> > anEnumValue2,
> >
> > ...
> > };
> > }
> >
> > }
> >
> > class myQtClassA : QObject {
> > ...
> >
> > Q_SIGNALS:
> > void
> > someSignal(X:Y:anEnum...);
> > ...
> > };
> >
> > class
> > myQtClassB: QObject {
> > ...
> > public
> > Q_SLOTS:
> > void someSlot(X:Y:anEnum);
> >
> > ...
> > };
> >
> > myQtClassB::someFunction(myQtClassA*
> > _a){
> > ...
> >
> > connect(_a,SIGNAL(someSignal(anEnum)),this,SLOT(someSlot(anEnum));
> >
> > ...
> > }
> >
> > TIA,
> >
> >
> > Ben
More information about the Qt-interest-old
mailing list