Qt Create 项目在某些情况下只创建Cpp文件情况,并在Cpp文件中添加继承自QObject类和引用Q_OBJECT宏,此时会无法避免的出现编译错误。
问题示例:
QtServiceWindows.cpp
class QtServiceControllerHandler : public QObject
{
Q_OBJECT
public:
QtServiceControllerHandler(QtServiceSysPrivate *sys);
protected:
void customEvent(QEvent *e);
private:
QtServiceSysPrivate *d_sys;
};
此时编译时会出现问题:
QtServiceWindows.obj : error LNK2001: 无法解析的外部符号 "public: virtual struct QMetaObject const * __cdecl QtServiceControllerHandler::metaObject(void)const "
(?metaObject@QtServiceControllerHandler@@UEBAPEBUQMetaObject@@XZ)
QtServiceWindows.obj : error LNK2001: 无法解析的外部符号 “public: virtual void * __cdecl QtServiceControllerHandler::qt_metacast(char const *)”
(?qt_metacast@QtServiceControllerHandler@@UEAAPEAXPEBD@Z)
QtServiceWindows.obj : error LNK2001: 无法解析的外部符号 “public:
virtual int __cdecl QtServiceControllerHandler::qt_metacall(enum QMetaObject::Call,int,void * *)”
(?qt_metacall@QtServiceControllerHandler@@UEAAHW4Call@QMetaObject@@HPEAPEAX@Z)
问题分析
- QT Create编译时会调用moc工具来生成moc_***文件,moc文件只会去将.h文件中继承OBJECT并引用了Q_OBJECT情况下才会生成moc文件,但Cpp文件不会去检查,这样就不能自动为该类添加一些实现函数(元对象函数),就会导致函数未定义的错误。
- 当qmake运行起来时,moc工具会自动识别处理头文件中所有继承于QObject的类和一系列Qt元对象属性。
- 如果需要让moc识别cpp文件,只需要包含#include 当前文件名称.moc就可以了。
解决方法
QtServiceWindows.cpp
class QtServiceControllerHandler : public QObject
{
Q_OBJECT
public:
QtServiceControllerHandler(QtServiceSysPrivate *sys);
protected:
void customEvent(QEvent *e);
private:
QtServiceSysPrivate *d_sys;
};
// 在此处添加#include "QtServiceWindows.moc"
#include "QtServiceWindows.moc"
清除项目构建,并且qmake,重新编译。