来自cmake的QT5生成的MOC文件中的错误

nav*_*erm 3 qt cmake moc qt5

我用QT5生成了moc文件

set (CMAKE_AUTOMOC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
Run Code Online (Sandbox Code Playgroud)

然后我使用moc文件添加到SRC

SET(SRC
  src/main.cpp
  src/video_widget_surface.cpp
  src/video_widget.cpp
  src/video_player.cpp
#moc files
  moc/moc_video_player.cpp
  moc/moc_video_widget.cpp
  moc/moc_video_widget_surface.cpp
Run Code Online (Sandbox Code Playgroud)

最后我使用添加可执行文件

add_executable(somegui ${SRC})
Run Code Online (Sandbox Code Playgroud)

但我在moc文件中遇到错误说:

/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:54:6: error: 'VideoWidget' has not been declared
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:62:19: error: 'VideoWidget' has not been declared
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:68:20: error: 'VideoWidget' has not been declared
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:68:46: error: non-member function 'const QMetaObject* metaObject()' cannot have cv-qualifier
/other/Qt5.0.1/5.0.1/gcc_64/include/QtCore/qobject.h: In function 'const QMetaObject* metaObject()':
/other/Qt5.0.1/5.0.1/gcc_64/include/QtCore/qobject.h:401:33: error: 'QScopedPointer<QObjectData> QObject::d_ptr' is protected
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:70:21: error: within this context
/other/Qt5.0.1/5.0.1/gcc_64/include/QtCore/qobject.h:401:33: error: invalid use of non-static data member 'QObject::d_ptr'
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:70:21: error: from this location
/other/Qt5.0.1/5.0.1/gcc_64/include/QtCore/qobject.h:401:33: error: 'QScopedPointer<QObjectData> QObject::d_ptr' is protected
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:70:50: error: within this context
/other/Qt5.0.1/5.0.1/gcc_64/include/QtCore/qobject.h:401:33: error: invalid use of non-static data member 'QObject::d_ptr'
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:70:50: error: from this location
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp: At global scope:
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:73:7: error: 'VideoWidget' has not been declared
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp: In function 'void* qt_metacast(const char*)':
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:77:47: error: expected type-specifier before 'VideoWidget'
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:77:47: error: expected '>' before 'VideoWidget'
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:77:47: error: expected '(' before 'VideoWidget'
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:77:47: error: 'VideoWidget' was not declared in this scope
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:77:59: error: expected primary-expression before '>' token
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:77:61: error: invalid use of 'this' in non-member function
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:77:67: error: expected ')' before ';' token
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:78:40: error: cannot call member function 'virtual void* QWidget::qt_metacast(const char*)' without object
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp: At global scope:
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:81:5: error: 'VideoWidget' has not been declared
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp: In function 'int qt_metacall(QMetaObject::Call, int, void**)':
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:83:43: error: cannot call member function 'virtual int QWidget::qt_metacall(QMetaObject::Call, int, void**)' without object
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp: In function 'void* qt_metacast(const char*)':
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:79:1: warning: control reaches end of non-void function [-Wreturn-type]
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp: In function 'const QMetaObject* metaObject()':
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:71:1: warning: control reaches end of non-void function [-Wreturn-type]
make[2]: *** [CMakeFiles/somestuff.dir/moc/moc_video_widget.cpp.o] Error 1
make[1]: *** [CMakeFiles/somestuff.dir/all] Error 2
make: *** [all] Error 2
Run Code Online (Sandbox Code Playgroud)

我的理解是在创建的moc文件中存在一些错误.但我无法控制如何创建它.现在我该如何解决这个bug?

Ale*_*aev 10

CMake文档并没有那么糟糕,不要忽视阅读它.你误解了AUTOMOC的概念:

AUTOMOC是一个布尔值,指定CMake是否将moc自动处理Qt 预处理器,即无需使用QT4_WRAP_CPP()宏.目前支持Qt4.当此属性设置TRUE为时,CMake将在构建时扫描源文件并相应地调用moc.如果找到#include类似的语句#include "moc_foo.cpp",Q_OBJECT则在头中需要类声明,并moc在头文件上运行.如果找到#include类似的语句#include "foo.moc",则Q_OBJECT在当前源文件中需要a,并moc在文件本身上运行.此外,所有头文件都被解析为Q_OBJECT宏,如果找到,moc也会对这些文件执行.

所以,首先,你应该加产生moc明确的文件源,并将其推入可执行文件汇编.换句话说,你只推动你的来源:

SET(SRC
  src/main.cpp
  src/video_widget_surface.cpp
  src/video_widget.cpp
  src/video_player.cpp)
Run Code Online (Sandbox Code Playgroud)

并且moc由CMake自动处理.

其次,如文件中所述:

  • 如果Q_OBJECTfoo.h(即QObject在头文件中声明),则在相应的中foo.cpp 不要忘记添加#include "moc_foo.cpp",最好在文件的末尾;

  • 如果Q_OBJECTfoo.cpp(即QObject在源文件中声明),那么,再次,在foo.cpp本身不要忘记添加#include "foo.moc",最好是在文件的末尾.