PDA

View Full Version : Signal/Slot methods



Micawber
3rd August 2007, 13:37
Hello,

I'm new to C++ and Qt. I was wondering if the methods used to connect signals with slots actually get called/executed? (I realize the slot gets called, otherwise it wouldn't be too useful ;) ) For example...


connect( this, SIGNAL( signalMethod( int signalArg ) ), someObject, SLOT( slotMethod( int slotArg ) ) );

when I emit the signal with...


emit signalMethod( someInt );

does the method "signalMethod()" get called with the argument "someInt" (if it is defined in the class) before the signal is delivered or is it just a placeholder of some sort for the moc?

Put another way if the signalMethod has code associated with it in the class definition, does that determine if it gets called or not?

Thanks for any insight.

marcel
3rd August 2007, 13:57
Yes, the meta object compiler adds a few methods to a class that implements signals/slots.
A method is added for every signal that you define in your class, with the same signature.

For example, for your signal example, in the source generated by moc you can find a method named signalMethod(int).

When you emit a signal( with emit), you actually call that auto-generated method.
This, in turn, calls QMetaObject::activate.
This checks to see if actually something is connected to this signal(a slot).
Further, the connection list of the object is investigated to find the destination object. Also, here is checked what kind of connection we have ( direct, queued ), plus a lot of other verifications.
Finally, qt_metacall is called, that actually calls the corresponding slot in the target object.

This is the big picture.

You could find out more by debugging and looking over what moc generates.

Regards

Micawber
3rd August 2007, 14:54
Thank you for that insight Marcel. It saved me a lot of digging.

I take it from your explanation of how it works, that it is not possible to have user specified code as a signal method. As in...


class fiddlestix {
Q_OBJECT

public signals:
void doThisWhenISignal( int foo );

};

fiddlestix::doThisWhenISignal( int foo )
{

foo += 53;

}



In other words, I cannot define a section of code that I wish to be executed every time I emit the signal that does something _before_ Qt starts operating on it?

marcel
3rd August 2007, 14:58
No, you cannot do that.
At most you can connect another slot to that signal, but before you connect the actual slot.
The first slot will get executed before the second. This is if you want to do something before the second slot is executed.
The connect order dictates the slot execution order for direct connections.

If you want to do something before actually the signal is emitted, you have only one chance: if you emit the signal yourself, i.e. by calling (emit signal). Then you could put some code before the emit statement.

EDIT: when declaring signals, you must not give them a visibility modifier( public, protected, private ). Just signals:. This is opposed to slots, where you always have to specify their visibility.

Regards

Micawber
3rd August 2007, 15:23
Got it. Thanks Marcel!

Also I take your point re: visibility of signals vs. slots. Good insight.