tags:

views:

85

answers:

4

Hi guys .. I basically have multiple events signals which I want to connect to the same slot. What I want to know is how can I pass string based paramters to that same slot so that the slot knows which is this signal coming from. One alternative is to make as many slots as there are signals and then connect them in a 1:1 manner, but this is efficient, considering that the code for all the processing is very similar. I tried doing this but I'm getting some errors:

connect(selecter1,SIGNAL(selected(QString)),this,SLOT(backgroundTypeChoiceMade(QString)));
connect(button1,SIGNAL(clicked()),this,SLOT(backgroundTypeChoiceMade("button1")));
connect(button2,SIGNAL(clicked()),this,SLOT(backgroundTypeChoiceMade("button2")));

The error is related to the parameters I'm passing in the last 2 commands .. And backgroundTypeChoiceMade is declared like this:

void backgroundTypeChoiceMade(QString);

Can someone tell me what the error is in the above code ?

+3  A: 

You can't pass constants to connect() because the effective parameters are deduced at execution time, not compile time.

However, while this is against the OO principle, you can use QObject::sender() which gives a pointer to the emitter QObject.

Example below:

void YourClass::YourClass() :
  m_button1(new QPushButton()),
  m_button2(new QPushButton())
{
  connect(m_button1, SIGNAL(clicked()), this, SLOT(yourSlot()));
  connect(m_button2, SIGNAL(clicked()), this, SLOT(yourSlot()));
}

void YourClass::yourSlot()
{
  if ((QPushButton* button = dynamic_cast<QPushButton*>(sender()))
  {
    // Now button points to a QPushButton* that you can compare with the pointers you already have

    if (button == m_button1)
    {
      // Whatever
    } else
    if (button == m_button2)
    {
      // Whatever
    }
  }
}

If you have many buttons, you may also use a QSignalMapper by providing an identifier for each button.

ereOn
One could also use the objectName-property: http://doc.trolltech.com/4.5/qobject.html#objectName-prop
Magnus Hoff
+4  A: 

You can use QSignalMapper. Although the QSignalMapper is the answer to your question, I think jon hanson's answer is the way you should take. You get much more cleaner code that way.

Roku
+5  A: 

What is inefficient about using separate slots? If there's commonality in the slot handlers then move that into a function, e.g. extending ereOn's example:

void YourClass::YourClass() :
  m_button1(new QPushButton()),
  m_button2(new QPushButton())
{
  connect(m_button1, SIGNAL(clicked()), this, SLOT(yourSlot1()));
  connect(m_button2, SIGNAL(clicked()), this, SLOT(yourSlot2()));
}

void YourClass::common(int n)
{
}

void YourClass::yourSlot1()
{
    common (1);
}

void YourClass::yourSlot2()
{
    common (2);
}
jon hanson
I totally agree with that.
ereOn
A: 

You can use something like I posted on my blog: http://uint32t.blogspot.com/2008/11/using-boost-bind-and-boost-function.html

I think one of the comments has a pretty good solution as well.

cheez