QT и новый синтаксис сигнального слота, слот для QApplication :: quit вне основной функции - PullRequest
0 голосов
/ 27 мая 2018

Я пытаюсь проверить старый и новый синтаксис слотов / сигналов QT.Старый стиль работает нормально, новый работает только в основной функции, он не работает, если мы передаем объект приложения другой функции.Компилятор VS 2017 генерирует ошибку C2665: «Параметр перегруженной функции не может быть преобразован в требуемый тип».

void testTimer(const QApplication& app)
{
    QTimer::singleShot(1000, &app, SLOT(quit())); // OK - works
    // This generates compiler error C2665:
    QTimer::singleShot(1000, &app, &QApplication::quit); // Compiler error
}

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QTimer::singleShot(1000, &app, SLOT(quit())); // OK - works
    QTimer::singleShot(1000, &app, &QApplication::quit); // OK - works

    testTimer(app);

    app.exec();
}

1 Ответ

0 голосов
/ 27 мая 2018

Почему?QCoreApplication::quit - это метод класса: ему вообще не нужен объект.Вы должны вызывать его как указатель на функцию C:

QTimer::singleShot(1000, &QCoreApplication::quit);

И даже если он это сделал - вы должны использовать qApp.Приложение по сути является глобальным синглтоном, время жизни которого вы контролируете.Передавать его не нужно.

Если вы попробуете его на реальном нестатическом элементе, вы увидите, что он работает просто отлично (протестировано с Qt 5.10).Qt даже позволяет вам выстрелить себе в ногу:

#include <QTimer>
#include <utility>

struct Foo : QObject {
   void slot() const {}
   void nonConstSlot() {}
};

void test(const Foo *foo) {
   QTimer::singleShot(900, foo, &Foo::slot);
}

template <typename P, typename M, typename> struct valid {
   static std::false_type value;
};

template <typename P, typename M> struct valid<P, M, decltype((*P().*M())())> {
   static std::true_type value;
};

template <typename P, typename M, typename ...Args> constexpr bool isValid(P, M, Args...) {
   return valid<P, M, void>::value;
}

int main() {
   const Foo foo;
   QTimer::singleShot(1000, &foo, &Foo::slot);
   QTimer::singleShot(1000, &foo, &Foo::nonConstSlot); //oops
   static_assert(isValid(&foo, &Foo::slot), "");
   static_assert(!isValid(&foo, &Foo::nonConstSlot), ""); // (foo.*&Foo::nonConstSlot)() must be invalid
   test(&foo);
   return 0;
}
...