Qt: Как узнать, был ли слот вызван механизмом сигнального слота, вызвав сигнал как функцию
Внутри слота я проверяю QObject::sender()
но теперь я хочу назвать этот слот напрямую как функцию.
Могу ли я узнать, как этот слот был назван внутри слота? Или с помощью механизма сигнальных слотов, или просто вызывая слот как функцию?
3 ответа
Добавьте параметр по умолчанию в ваш слот:
public slots: void slot(bool calledBySignal = true);
Установите параметр в false при вызове слота напрямую:
void MyClass::method() { [...] slot(false); [...] }
Оставь
connect()
звонки как они есть; не добавляйте параметр bool к сигналам и не изменяйтеSLOT(slot())
вSLOT(slot(bool))
,
Недостаток: настройку параметра легко забыть.
Если ваш слот не должен быть публичным, потому что connect()
Поскольку он обрабатывается только внутри класса, вы должны сделать его закрытым и добавить метод-обертку, который будет вызываться вместо этого, но все же вам потребуется некоторая дисциплина при вызове его из класса. Предложение Йоханнеса решило бы эти проблемы.
Вы можете проверить sender()
в обоих случаях. В случае, если слот вызывается через механизм сигнал / слот, отправитель возвращает указатель, а при вызове в качестве метода он возвращает нулевой указатель.
Простой пример:
class Test : public QObject
{
Q_OBJECT
signals:
void signal();
public slots:
void slot() { qDebug() << sender(); }
};
И использование:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Test test;
Test test2;
QObject::connect(&test, &Test::signal, &test2, &Test::slot);
test.signal(); //slot is caled by signal
test2.slot(); //slot is called as method directly
return a.exec();
}
И вывод:
Тест (0xa8e8aff5b0)
QObject (0x0)
Еще одна идея, чтобы отличить прямой вызов функции от вызова сигнала / слота:
Используйте метод int QObject::senderSignalIndex() const и проверьте -1
if(QObject::senderSignalIndex() == -1){
//called directly as a function
} else {
// invoked via Signal/SLot mechanism
}
Возвращает индекс мета-метода для сигнала, вызвавшего текущий исполняемый слот, который является членом класса, возвращаемого sender(). Если вызывается вне слота, активированного сигналом, возвращается -1.
смотрите документацию по Qt 4.8
Это выглядит как чистый способ различения, и нет никаких шансов попасть в неприятности с нулевым указателем в отличие от использования QObject * QObject::sender() const
,
С уважением, Феликс