April 18, 2011

rudag rudag
Lab Rat
10 posts

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:

  1. connect(bt, SIGNAL(clicked()), this, SLOT(save(1)));

Help?

12 replies

April 18, 2011

vinb vinb
Lab Rat
205 posts

Read this [doc.qt.nokia.com] carefully.

And notice that a signal can not have less arguments then the called slot. So you have to get your int from elsewhere.

April 18, 2011

harry harry
Lab Rat
108 posts

I always use QSignalMapper when having to deal with things like that.

 Signature 

If you can’t say what you mean, you’ll never be able to mean what you say.

April 18, 2011

ZapB ZapB
Ant Farmer
1424 posts

Agreed, QSignalMapper is your friend in this case.

 Signature 

Nokia Certified Qt Specialist
Interested in hearing about Qt related work

April 18, 2011

vinb vinb
Lab Rat
205 posts

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?

April 18, 2011

Andre Andre
Robot Herder
6395 posts

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 ™ will.

April 18, 2011

vinb vinb
Lab Rat
205 posts

Ah ok,
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?

April 18, 2011

Andre Andre
Robot Herder
6395 posts

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.

April 18, 2011

vinb vinb
Lab Rat
205 posts

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?

April 18, 2011

ZapB ZapB
Ant Farmer
1424 posts
Andre wrote:
It is only possible to pass arguments to a slot, that are passes by the signal.

Or via QMetaObject::invokeMethod() but that is a different use case than what we have here. ;-)

 Signature 

Nokia Certified Qt Specialist
Interested in hearing about Qt related work

April 18, 2011

ZapB ZapB
Ant Farmer
1424 posts

vinb wrote:
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?

All you need is something like this:

  1. MyClass::MyClass( QWidget* parent )
  2.  : QWidget( parent ),
  3.    m_signalMapper( new QSignalMapper( this ) )
  4. {
  5.     ui->setupUi( this );
  6.  
  7.     // Map button to an int
  8.     m_signalMapper->addMapping( ui->button, 1 );
  9.     connect( ui->button, SIGNAL( clicked() ), m_signalMapper, SLOT( map() ) );
  10.  
  11.     // Use signal mapper instead of button to trigger slot
  12.     connect( m_signalMapper, SIGNAL( mapped( int ), this, SLOT( save( int ) ) );
  13. }
  14.  
  15. void MyClass::save( int i )
  16. {
  17.     qDebug() << "Called via button mapped to int value of" << i;
  18.     ...
  19. }

No need to subclass anything here.

 Signature 

Nokia Certified Qt Specialist
Interested in hearing about Qt related work

April 18, 2011

Andre Andre
Robot Herder
6395 posts

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.

April 18, 2011

vinb vinb
Lab Rat
205 posts

Thanks for showing ZapB and Andre for the explaining!

 
  ‹‹ (absolute beginner) QCoreApplication      Item Model/View Selection/ScrollTo ››

You must log in to post a reply. Not a member yet? Register here!