从cmake生成QT5的MOC文件中的错误 [英] Errors in generated MOC files for QT5 from cmake

查看:442
本文介绍了从cmake生成QT5的MOC文件中的错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用

为QT5生成了moc文件

 设置(CMAKE_AUTOMOC ON)
设置(CMAKE_INCLUDE_CURRENT_DIR ON)

然后我使用



<$>将moc文件添加到SRC p $ p> 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

最后,我使用

  add_executable(somegui $ {SRC})添加可执行文件

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

  /other/workspace/perception/somestuff/moc/moc_video_widget.cpp:54:6:错误:VideoWidget尚未声明
/ other / workspace / perception /somestuff/moc/moc_video_widget.cpp:62:19:错误:'VideoWidget'尚未声明
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:68:20:错误:'VideoWidget'没有被声明
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:68:46:错误:非成员函数'const QMetaObject * metaObject()'不能有cv-qualifier
/other/Qt5.0.1/5.0.1/gcc_64/include/QtCore/qobject.h:在函数'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:错误:在此上下文中
/other/Qt5.0.1/5.0.1/ gcc_64 / include / QtCore / qobject.h:401:33:错误:无效使用非静态数据成员'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:错误:在此上下文中
/other/Qt5.0.1/5.0.1/ gcc_64 / include / QtCore / qobject.h:401:33:错误:无效使用非静态数据成员'QObject :: d_ptr'
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:70 :50:错误:从这个位置
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:在全局范围:
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp: 73:7:错误:'VideoWidget'尚未声明
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:在函数'void * qt_metacast(const char *)':
/其他/ workspace / perception / somestuff / moc / moc_video_widget.cpp:77:47:错误:VideoWidget之前的预期类型说明
/other/workspace/perception/somestuff/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'
/其他/ workspace / perception / somestuff / moc / moc_video_widget.cpp:77:47:错误:VideoWidget未在此范围内声明
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:77: 59:错误:'>'令牌之前的预期主表达式
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:77:61:错误:在非成员函数中无效使用this
/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:错误:无法调用成员函数'virtual void * QWidget :: qt_metacast(const char *)'没有对象
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:在全局范围:
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:81:5:错误:VideoWidget尚未声明
/ other / workspace / perception / somestuff / moc / moc_video_widget .cpp:在函数'int qt_metacall(QMetaObject :: Call,int,void **)':
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:83:43:error:can not call member function'virtual int QWidget :: qt_metacall(QMetaObject :: Call,int,void **)'无对象
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:在函数'void * qt_metacast char *)':
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:79:1:warning:控制到达非void函数的结束[-Wreturn-type]
/ other /workspace/perception/somestuff/moc/moc_video_widget.cpp:在函数'const QMetaObject * metaObject()':
/other/workspace/perception/somestuff/moc/moc_video_widget.cpp:71:1:warning:control到达结束非空函数[-Wreturn-type]
make [2]:*** [CMakeFiles / somestuff.dir / moc / moc_video_widget.cpp.o]错误1
make [1] :*** [CMakeFiles / somestuff.dir / all]错误2
make:*** [all]错误2

我的理解是,在创建的moc文件中有一些错误。但我没有任何控制如何创建。现在我该如何解决这个错误?

解决方案

CMake文档不是那么糟,不要忽略阅读。您误解 AUTOMOC 的概念:


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

因此,首先,您应该添加生成的 moc 显式地将文件推送到源代码,并将其推入可执行编译。换句话说,你只推你的来源:

  SET(SRC 
src / main.cpp
src / video_widget_surface.cpp
src / video_widget.cpp
src / video_player.cpp)

moc 由CMake自动处理。



其次,如文档中所述: p>


  • 如果 Q_OBJECT 位于 foo.h (即 QObject 在头文件中声明),
    然后在相应的 foo.cpp
    不要忘记添加 #includemoc_foo.cpp,最好在文件的末尾
    ; p>


  • 如果 Q_OBJECT 位于 foo.cpp (即 QObject 在源文件中声明),
    然后再次在 foo.cpp 本身
    不要忘记添加 #includefoo.moc,最好在文件的结尾

    li>

I generated moc files for QT5 using

set (CMAKE_AUTOMOC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)

Then I add the moc files into SRC using

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

Finally I add the executable using

add_executable(somegui ${SRC})

But I get errors in moc files saying :

/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

My understanding is that there is some error in the moc files that are created. But I don't have any control over how that is created. Now how do I solve this bug ?

解决方案

CMake documentation is not that bad, do not neglect reading it. You misunderstood the concept of AUTOMOC:

AUTOMOC is a boolean specifying whether CMake will handle the Qt moc preprocessor automatically, i.e. without having to use the QT4_WRAP_CPP() macro. Currently Qt4 is supported. When this property is set to TRUE, CMake will scan the source files at build time and invoke moc accordingly. If an #include statement like #include "moc_foo.cpp" is found, the Q_OBJECT class declaration is expected in the header, and moc is run on the header file. If an #include statement like #include "foo.moc" is found, then a Q_OBJECT is expected in the current source file and moc is run on the file itself. Additionally, all header files are parsed for Q_OBJECT macros, and if found, moc is also executed on those files.

So, first of all, you should not add generated moc files explicitly to sources and push them into executable compilation. In other words, you only push your sources:

SET(SRC
  src/main.cpp
  src/video_widget_surface.cpp
  src/video_widget.cpp
  src/video_player.cpp)

and moc ones are handled automatically by CMake.

Secondly, as stated in the documentation:

  • If Q_OBJECT is in the foo.h (i.e. QObject is declared in the header file), then in the corresponding foo.cpp don't forget to add #include "moc_foo.cpp", preferably at the end of the file;

  • If Q_OBJECT is in the foo.cpp (i.e. QObject is declared in the source file), then, again, in the foo.cpp itself don't forget to add #include "foo.moc", preferably at the end of the file.

这篇关于从cmake生成QT5的MOC文件中的错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆