QT和新的信号槽语法,QApplication :: slot在主函数外部退出

时间:2018-05-27 09:57:50

标签: c++ qt signals-slots

我正在尝试测试旧的和新的QT插槽/信号语法。旧样式工作正常,新的只能在main函数中工作,如果我们将app对象传递给另一个函数它不起作用。 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 :(得分:0)

为什么呢? 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;
}