QT 和新的信号槽语法,用于 QApplication::quit 外部主函数的槽

Posted

技术标签:

【中文标题】QT 和新的信号槽语法,用于 QApplication::quit 外部主函数的槽【英文标题】:QT and the new signal slot syntax, slot for QApplication::quit outside main function 【发布时间】:2018-05-27 09:57:49 【问题描述】:

我正在尝试测试新旧 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();

【问题讨论】:

您需要在不称为main() 的函数中尝试与main() 完全相同的代码。 更改为void testTimer(QApplication *app)QTimer::singleShot(1000, app, &QApplication::quit); testTimer(&app); 我的代码在 main 和 testTimer 函数中完全一样。我也尝试使用指向应用程序的指针,但它给出了相同的结果。 @Klearuegh 一个疯狂的猜测 - 从 QApplication& app 函数 testTimer 参数中删除 const?注意:quit 是一个静态插槽,完全不确定为什么一个对象会在这里相关 非常感谢,删除 const 后没有编译器错误。我花了 2 个小时在上面:) 【参考方案1】:

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

【讨论】:

感谢您的回答。我在测试新样式语法时不知道问题出在哪里。除非您手动进行类型转换,否则您似乎无法以新样式使用常量。未来的教训。 @Klearuegh 这是错误的。

以上是关于QT 和新的信号槽语法,用于 QApplication::quit 外部主函数的槽的主要内容,如果未能解决你的问题,请参考以下文章

QT-自定义信号和槽

qt中的信号和槽机制

使用带有新信号槽语法的 Qt 插件系统在接口类中声明信号

Qt之信号槽连接——基于字符串与基于函数的连接之间的不同(译)

QT信号槽实现原理

Qt 6.x中的信号和槽介绍及示例