Podłączam dwa sygnały do tego samego szczeliny. lubię to:

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

Nie chcę definiować innego gniazda. W MySlot Czy możliwe jest rozpoznanie, które oddzwonienia sygnału gniazdo? Jak mogę to zrobić?

1
M.Hu 3 czerwiec 2018, 14:38

3 odpowiedzi

Najlepsza odpowiedź

Możesz użyć danych QMetaObject / QMetaMethod związanych z nadawcą, aby uzyskać to, co chcesz (nieświadomie) ...

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.
     */
  }
}

Jednakże jednak, jeśli używasz QT5, sugerowałbym korzystanie z nowej składni sygnału / slotu wraz z Lambdas ...

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

Wraz ze zmianą podpisu 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)
{
  .
  .
  .
}
3
G.M. 3 czerwiec 2018, 12:58

Nowe automaty można zdefiniować w lopieniu za pomocą 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); });
  }
};
2
Reinstate Monica 4 czerwiec 2018, 16:47

Możesz także dodać własny kontekst do sygnału, jeśli to pomoże. Na przykład przeprowadziłem usługę, która pobrała awatary użytkownika dla wielu okien. Potrzebowałem okna, aby ładować tylko użytkownik, którego interesuje, więc przekazałbym identyfikator użytkownika jako kontekst. Coś jak:

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

  emit onAvatarDownloaded(context, responseBody);

}
0
CaptRespect 4 czerwiec 2018, 18:08