Parameters through the signal clicked()
I have a QPushButton and I need to connect this button with the save(int i) function. I tried this, but didn't worked:
@connect(bt, SIGNAL(clicked()), this, SLOT(save(1)));@
Read "this":http://doc.qt.nokia.com/stable/signalsandslots.html#signals-and-slots-with-default-arguments carefully.
And notice that a signal can not have less arguments then the called slot. So you have to get your int from elsewhere.
I always use QSignalMapper when having to deal with things like that.
Agreed, QSignalMapper is your friend in this case.
Ok, but then i really dont understand the question |& the signalmapper.
What i am reading, only explains how to make corresponding signal/slots from an array of objects with the mapper.
I cant find an explanation about how i can pass an argument to the slot, when i dont have a signal with a corresponding given parameter.
Can you explain a little more please?
The need to pass a fixed argument to a slot, arises when you call that same slots from multiple senders and you need to distinguish between them. QSignalMapper allows you to do this.
While it does not make it possible to set an argument for a slot directly, it does make it possible to do so indirectly by associating a sender with an argument.
The basic mistake the rudag makes, is that he or she tries to use a function call instead of a function signature in the SLOT macro. That doesn't work, and never (TM) will.
So i wasnt reading wrong. If i understand it correctly, Its not possible to pass an argument to a slot, accept an argument given by the signal or the id of the sender trough the mapper.
Am i right?
It is only possible to pass arguments to a slot, that are passed by the signal.
On top of that, a QObject::sender() will return the QObject that send the signal that caused the current slot invokation (or 0, if there is no such object). QSignalmapper uses that to map such a sender to an argument, which is then emitted as the mapped(<argument type>) signal.
thanks for clearing that out, Andre!
So i workaround is, to subclass the sender object and add a property to it wich you can pass trough a signal?
[quote author="Andre" date="1303115932"]It is only possible to pass arguments to a slot, that are passes by the signal.[/quote]
Or via QMetaObject::invokeMethod() but that is a different use case than what we have here. ;-)
[quote author="vinb" date="1303116418"]thanks for clearing that out, Andre!
So i workaround is, to subclass the sender object and add a property to it wich you can pass trough a signal?[/quote]
All you need is something like this:
MyClass::MyClass( QWidget* parent )
: QWidget( parent ),
m_signalMapper( new QSignalMapper( this ) )
ui->setupUi( this );
// Map button to an int m_signalMapper->addMapping( ui->button, 1 ); connect( ui->button, SIGNAL( clicked() ), m_signalMapper, SLOT( map() ) ); // Use signal mapper instead of button to trigger slot connect( m_signalMapper, SIGNAL( mapped( int ), this, SLOT( save( int ) ) );
void MyClass::save( int i )
qDebug() << "Called via button mapped to int value of" << i;
No need to subclass anything here.
There are several workarounds:
- Use QSignalMapper. That works for many scenario's, and should probably be your number 1 solution to investigate.
- Subclass the sender object to emit a signal with the information you need directly, and connect to that signal instead.
- Use the QObject::sender() method (though I prefer to use QSignalMapper::mapped(QObject*) in such cases, as it is saver).
- Use different receiver slots on a single object
- Use different receiver objects with a slot of the same name
The last two are probably not used often in practice, especially if the number of possible arguments is larger than a few.
Note that you can use dynamic properties on the sender objects too, perhaps in conjunction with a QSignalMapper or with the sender() method. This allows you to set one or more values under known names on each of the possible sender objects, that you can query from your receiver slot. Downside of this (and other uses of information on the sender object) is that you get a tight coupling between the sender and the receiver.
Thanks for showing ZapB and Andre for the explaining!