我正在尝试测试旧的和新的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();
}
答案 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;
}