M.Hu
M.Hu

Reputation: 141

how to recognize which signal emitted in slot?

I connect two signals to same slot. like this:

check = new QCheckBox();
connect(check, SIGNAL(clicked()), this, SLOT(MySlot()));
connect(check, SIGNAL(toggled(bool)),this,SLOT(MySlot()));

I don't want to define an other slot. In MySlot is it possible to recognize which signal callbacks the slot? How can I do this?

Upvotes: 1

Views: 263

Answers (3)

CaptRespect
CaptRespect

Reputation: 2055

You can also add your own context to the signal if that helps. For instance I had a service that downloaded user avatars for multiple windows. I needed the window to only load the user it was interested in something so I would pass in the user's id as the context. Something like:

void UserService::downloadAvatar(const QString& url, const int context = 0) {
  ...// Make the http request, on finished:

  emit onAvatarDownloaded(context, responseBody);

}

Upvotes: 0

New slots can be defined on the fly using lambdas :)

class MyClass : public QWidget {
  QSomeLayout m_layout{this};
  QCheckBox m_check;
  enum Signal { Clicked, Toggled };

  Q_SLOT void mySlot(Signal);
public:
  MyClass( ... ) : ... {
    m_layout.addWidget(&m_check);
    connect(&m_check, &QCheckBox::clicked, this, [this]{ mySlot(Clicked); });
    connect(&m_check, &QCheckBox::toggled, this, [this]{ mySlot(Toggled); });
  }
};

Upvotes: 2

G.M.
G.M.

Reputation: 12879

You might be able to use the QMetaObject/QMetaMethod data associated with the sender to get what you want (untested)...

void MyClass::MySlot ()
{
  auto index = senderSignalIndex();
  if (index == sender()->indexOfSignal("clicked()")) {

    /*
     * Got here as the result of a clicked() signal.
     */
  } else if (index == sender()->indexOfSignal("toggled(bool)")) {

    /*
     * Got here as the result of a toggled(bool) signal.
     */
  }
}

Rather than that, however, if you're using Qt5 I would suggest making use of the new signal/slot syntax along with lambdas...

check = new QCheckBox();
connect(check, &QCheckBox::clicked,
        [this]()
        {
          MySlot(false);
        });
connect(check, &QCheckBox::toggled,
        [this](bool toggled)
        {
          MySlot(true, toggled);
        });

Along with a change to the signature of MySlot...

/**
 * @param from_toggled_signal If true this call was triggered by a
 *                            QCheckBox::toggled signal, otherwise it's
 *                            the result of a QCheckBox::clicked signal.
 *
 * @param toggle_value If from_toggled_signal is true then this was the
 *                     value passed to QCheckBox::toggled, otherwise unused.
 */
void MyClass::MySlot (bool from_toggled_signal, bool toggle_value = false)
{
  .
  .
  .
}

Upvotes: 3

Related Questions