Qt: Как узнать, был ли слот вызван механизмом сигнального слота, вызвав сигнал как функцию

Внутри слота я проверяю QObject::sender() но теперь я хочу назвать этот слот напрямую как функцию.

Могу ли я узнать, как этот слот был назван внутри слота? Или с помощью механизма сигнальных слотов, или просто вызывая слот как функцию?

3 ответа

  1. Добавьте параметр по умолчанию в ваш слот:

    public slots:
        void slot(bool calledBySignal = true);
    
  2. Установите параметр в false при вызове слота напрямую:

    void MyClass::method()
    {
        [...]
        slot(false);
        [...]
    }
    
  3. Оставь 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,

С уважением, Феликс

Другие вопросы по тегам