我从QObject继承了一个类:
class Parent: public QObject
{
Q_OBJECT
QObject* cl;
public:
Parent(QObject *parent=0):QObject(parent) {
cl = NULL;
}
QObject* getCl() const {
return cl;
}
void setCl(QObject *obj) {
cl = obj;
}
};
但是当我写道:
Parent ev;
我收到以下错误:
main.obj:-1: error: LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __thiscall Parent::metaObject(void)const " (?metaObject@Parent@@UBEPBUQMetaObject@@XZ)
main.obj:-1: error: LNK2001: unresolved external symbol "public: virtual void * __thiscall Parent::qt_metacast(char const *)" (?qt_metacast@Parent@@UAEPAXPBD@Z)
main.obj:-1: error: LNK2001: unresolved external symbol "public: virtual int __thiscall Parent::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@Parent@@UAEHW4Call@QMetaObject@@HPAPAX@Z)
答案 0 :(得分:64)
您应该删除应用程序的debug
文件夹并再次运行以纠正此问题。
答案 1 :(得分:55)
如果您正在使用Visual Studio,请从头文件中删除行Q_OBJECT
,保存文件,将Q_OBJECT
放回头文件,再次保存文件。这应该生成moc_*
文件,并且应该正确构建和链接。
答案 2 :(得分:29)
我注意到一些答案基于Visual Studio。
这个答案基于Qt Creator。
与名称建议不同,Rebuild Project
不会消除所有内容并从头开始构建。如果您最近在课程中添加了QObject
(和/或Q_OBJECT),则必须再次运行qmake
,例如
这是因为,默认情况下,qmake
仅在您对解决方案进行重大更改(例如添加新源文件或修改.pro
文件)时运行。如果您对现有文件进行了编辑,则不知道它需要运行qmake
。
作为后退,要强行Qt从头开始构建所有内容,请删除Debug
或Release
文件夹。
答案 3 :(得分:8)
所以问题是我需要Qt MOC编译器来编译我的.h文件。对于任何扩展QObject或其子项之一的类,都需要这样做。修复了(对我来说)修复程序右键单击头文件,选择属性,并将项类型设置为“Qt MOC输入”,然后在标题上点击“编译”,然后将生成的moc_myfilename.cpp文件添加到我的项目
答案 4 :(得分:7)
如果您的moc文件是在visual studio项目中生成的,如果它们未包含在项目中,则尝试将它们包含到项目中,然后重建。
答案 5 :(得分:6)
我在Visual Studio中遇到了同样的问题,并通过以下步骤解决了这个问题:
然后在自定义构建工具配置中:
将“命令行”设置为:
“$(QTDIR)\ bin \ moc.exe”“%(FullPath)” - o“。\ GeneratedFiles \ $(ConfigurationName)\ moc _%(Filename).cpp”“ - fStdAfx.h”“ - f ../../../ src / FileName.h “-DUNICODE -DWIN32 -DWIN64 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB -DQT_NETWORK_LIB -DWIN32_LEAN_AND_MEAN -DDIS_VERSION = 7 -D_MATH_DEFINES_DEFINED “-I。\ SFML_STATIC”“ - I。\ GeneratedFiles”“ - I。” “-I $(QTDIR)\ include”“ - I。\ GeneratedFiles \ $(ConfigurationName)。” “-I $(QTDIR)\ include \ QtCore”“ - I $(QTDIR)\ include \ QtGui”“ - I $(QTDIR)\ include \ QtNetwork”
将“输出”设置为:
。\ GeneratedFiles \ $(ConfigurationName)\ moc _%(文件名).cpp
将“附加依赖项”设置为:
$(QTDIR)\ BIN \ moc.exe;%(FULLPATH)
您的确切值可能会有所不同。它们通常通过Qt插件应用。
答案 6 :(得分:4)
我使用CMake来管理Qt项目,并且需要在QT4_WRAP_CPP调用下添加新的Q_OBJECT。这将生成包含在项目中的moc _ * .cxx并清理未解析的外部。
答案 7 :(得分:3)
当我在cpp文件中有一个Q_OBJECT类定义时,我在Visual Studio 2012中遇到了这个问题。将类定义移动到头文件解决了这个问题。
看起来应该可以通过将cpp文件添加到moc来支持cpp文件中的Q_OBJECT类,但我没有尝试过这个。
答案 8 :(得分:2)
我手动将cpp / ui文件添加到我的项目中,但忘记将头文件显式添加为头文件。现在编译时我收到了类似的错误信息,并且在构建的调试(或发布)目录中没有生成moc _ * .cpp文件。这不是一个明显的错误,qmake没有抱怨,除了链接器消息我没有错误。
因此,如果有人再次遇到同样的问题(或者造成相同的副本和错误):确保标题文件也已添加到项目文件中
答案 9 :(得分:1)
在使用“ PIMPL ”(私有实现)编程模式时,在Qt中使用“私有类”时遇到了这个问题。 Qt在他们的源代码中使用了这个模型。我自己也非常喜欢它。
这种技术涉及在公共头文件中使用“私有”前向声明的类,它将被“公共”类(即它的“父”)使用。然后父节点指向私有类的实例作为数据成员。
“私有”类完全在公共cpp文件中定义。私有类没有头文件。
所有“肮脏的工作”都是通过私人课程完成的。这隐藏了公共类的所有实现,包括通常的每个其他私有成员(包括数据和函数)。
我强烈建议您了解PIMPL模式 - 特别是如果您要阅读内部Qt源代码。
没有进一步解释编码风格,这里是与这个问题相关的要点...要使Q_OBJECT
宏在cpp内工作,“private”类为QObject,可以使用信号/插槽等,你需要明确地将.moc包含在cpp内的公共类中:
#include "MyPublicClass.moc"
您可以忽略有关此行的任何IDE警告。
我不确定它是否真正起作用,但是我总是看到包含在私有类定义之后,而不是在cpp的顶部(如包括通常放置)。所以,cpp布局是这样的:
答案 10 :(得分:1)
在VS2010中使用QtAdd-in我意识到moc _ * .cpp文件已在GeneratedFiles / Debug文件夹中更新,尽管我处于发布模式。将文件复制到Release文件夹对我有用。
答案 11 :(得分:1)
在我的情况下(使用VS2012和Qt v4.8.4的QtAdd-in)上述建议都没有奏效。 由于某种原因,VS无法生成正确的moc文件(构建输出:没有找到相关的类。没有生成输出。)当我手动编译相关的头文件(将qt moc设置为编译器并单击“编译”)时,它生成了空的moc文件。
从命令行(moc -o moc_SomeClass.cpp SomeClass.h)编译所有必要的mocs然后在GeneratedFiles文件夹中替换错误的mocs是做了什么工作。
这只是解决方法(对于大型项目而言不是一个方便的方法)让您的项目成功构建,但并不能真正解释奇怪的VS / QtAdd-in行为。
答案 12 :(得分:1)
我的问题是我使用Qt宏的文件之一没有被移动。我发现,用于Visual Studio的Qt插件无法识别Q_NAMESPACE
宏,因此不会将文件添加到活动列表中。
因此,我使用了this answer中的解决方案将文件添加到麦克风列表中:
您应该找到一个已成功生成的.h文件 “ moc_ *”,然后复制“自定义构建工具->常规”中的所有内容 进入新的.h文件设置页面。
请注意Debug
和Release
模式的不同选项。
然后,构建您的项目。
在Debug
和Release
模式下分别构建一次
最后,将生成的“ moc_ *”文件添加到您的项目中。
现在,“ moc_filename.cpp”应该位于Generated Files\Debug
和Generated Files\Release
中。
右键单击它们,然后更改其属性:
Debug
中的文件:将配置更改为Release
,然后将General->Excluded from build
更改为yes
。Release
中的文件:将配置更改为Debug
,然后将General->Excluded from build
更改为yes
。答案 13 :(得分:1)
Visual Studio 2017。
我已将文件添加到已经设置的Qt项目中,并收到此错误。我如何解决它:
右键单击解决方案资源管理器中的标题 属性... -> 配置属性-> 常规-> 项目类型 从 C / C ++标头更改为 Qt元对象编译器(moc)
瞧:)
答案 14 :(得分:0)
最近在从MingW切换到MSVC时发生了这种情况。我有一个原型类/结构列为一个类,而MingW并不介意。
当涉及原型设计时,MSVC肯定会看到class
和struct
之间的差异。
希望有一天能帮助别人。
答案 15 :(得分:0)
在我的情况下,以上都没有奏效,但这完全是我的错误。
我在.h文件中覆盖了虚函数(声明了它们),但从未在.cpp中定义过它们。)
答案 16 :(得分:0)
我通过将其添加到我的头文件中解决了我的问题:
#ifndef MYCLASSNAME_H
#define MYCLASSNAME_H
... // all the header file content.
#endif
答案 17 :(得分:0)
这两个答案都适用于VS 2013环境。我最终通过从项目中删除 .h / .cpp并将其添加回来解决了这个问题。
答案 18 :(得分:0)
我在VS2015中使用集成的Perforce p4v客户端。 在我的情况下,Perforce尝试将moc文件添加到depo,当我恢复此操作时,Perforce从项目中删除了此moc文件并将其删除。 该文件在下一次编译后重新创建,但它没有包含在项目中,我必须手动将其添加到生成的文件中,当我终于明白问题是什么时。
答案 19 :(得分:0)
我遇到了同样的问题,我的解决方案是编码(我的文件“ UTF16LE BOM”无法通过moc.exe生成),使用ASCII编码创建另一个文件即可。
HxD HexEditor可以帮助您查看编码。
答案 20 :(得分:0)
我知道这是一个非常老的问题,但是它似乎仍然很有趣(在过去的几个月中,我至少来过4到5次),而且似乎我发现了另一个可能得到解决的原因这个错误。
在我的头文件中,我键入错误:
#include "MyClass.h""
仅在检查了整个输出后,我才发现编译器在那一行发出警告。
现在,我删除了附加引号,我的QObject可以完美编译!
答案 21 :(得分:0)
这是我的原因:QT的项目文件中未包含某些标头或源文件
答案 22 :(得分:0)
在链接有CMake目标的情况下解决了此问题。原来,即使在不直接(传递)使用Qt的目标中,我也必须启用CMAKE_AUTOMOC
。同样证明,CMAKE_AUTOMOC
不能与父级的同一find_package(QtX)
或CMakeLists.txt
中的CMakeLists.txt
一起使用。
答案 23 :(得分:0)
在我的情况下,项目子文件夹中存在问题的QObject祖先的.h和.cpp文件。当我将它们移到CMakeLists.txt(项目根文件夹)旁边时,它已成功链接。我可能会丢失一些CMake命令,以在子目录中包含Mocs FOT文件。