我有一个控制台应用程序,其中一个QCoreApplication
在main()
中运行事件循环。
在这里,我有一个对象,它是QThread的派生对象,实现了run()
以进行一些测试。
我希望线程在启动应用程序时启动,所以我调用了
QMetaObject::invokeMethod(&threadObj, &QThread::start, Qt::QueuedConnection);
return qapp.exec();
main()
的结尾。
这是我的问题:为什么不编译?
对QThread::quit
进行相同的操作可以正常工作,而QThread::exit
则不能。
我认为它与start
和exit
的参数有关?
编译器错误如下所示:
d:\dev\project\project\main.cpp(49): error C2665: 'QMetaObject::invokeMethod': none of the 4 overloads could convert all the argument types
1>x:\hmi_qt5\qt\msvc2017_x86\debug\include\qtcore\qobjectdefs.h(448): note: could be 'bool QMetaObject::invokeMethod(QObject *,const char *,QGenericArgument,QGenericArgument,QGenericArgument,QGenericArgument,QGenericArgument,QGenericArgument,QGenericArgument,QGenericArgument,QGenericArgument,QGenericArgument)' (compiling source file main.cpp)
1>x:\hmi_qt5\qt\msvc2017_x86\debug\include\qtcore\qobjectdefs.h(431): note: or 'bool QMetaObject::invokeMethod(QObject *,const char *,Qt::ConnectionType,QGenericArgument,QGenericArgument,QGenericArgument,QGenericArgument,QGenericArgument,QGenericArgument,QGenericArgument,QGenericArgument,QGenericArgument,QGenericArgument)' (compiling source file main.cpp)
1>x:\hmi_qt5\qt\msvc2017_x86\debug\include\qtcore\qobjectdefs.h(414): note: or 'bool QMetaObject::invokeMethod(QObject *,const char *,QGenericReturnArgument,QGenericArgument,QGenericArgument,QGenericArgument,QGenericArgument,QGenericArgument,QGenericArgument,QGenericArgument,QGenericArgument,QGenericArgument,QGenericArgument)' (compiling source file main.cpp)
1>d:\dev\project\project\main.cpp(49): note: while trying to match the argument list '(threadObj*, void (__thiscall QThread::* )(QThread::Priority), Qt::ConnectionType)'
预先感谢
鲍勃
PS:
通过使用函子或在threadObj
中实现自定义插槽,我确实有解决方法。
我问这个问题是因为我很好奇为什么这样做不起作用,因为我认为语法很好。
答案 0 :(得分:1)
问题是存在QThread::start
参数(尽管默认),并且在QMetaObject::invokeMethod
最重要的重载被定义为const char *member
作为第二个方面,Qt被破坏了。参数。因此,使用这些重载之一可以直接使用它:
#include <functional>
#include <QtWidgets/QApplication>
#include <QtWidgets/QtWidgets>
#include <QtWidgets/QMainWindow>
#include <QThread>
int main(int argc, char *argv[]) {
QThread threadObj;
QMetaObject::invokeMethod(&threadObj, "start", Qt::QueuedConnection);
QApplication this_application(argc, argv);
return this_application.exec();
}
另一种解决方法是
QMetaObject::invokeMethod(&threadObj, std::bind(&QThread::start,std::ref(threadObj),QThread::InheritPriority), Qt::QueuedConnection);
与lambda几乎相同,但是恕我直言,意图更明确。
答案 1 :(得分:0)
所以看来我找到了答案。
正如我最初预期的那样,问题不在于Qt内,而是C ++内。
使用函数指针进行间接函数调用时,只能调用参数列表为空的函数。 (如QThread::quit(void)
)
当调用具有参数列表(包括默认参数)的函数时,它将使用显式参数隐式调用该函数。这在这里不起作用,因为在functoin指针中不能有参数。
实现此目标的正确方法似乎是lambda。
QMetaObject::invokeMethod(&threadObj, [&threadObj]() {threadObj.start(); }, Qt::QueuedConnection);
这样,您仍然可以在编译时检查语句的有效性。
问候,鲍勃