ChatGPT解决这个技术问题 Extra ChatGPT

未解析的外部符号“public: virtual struct QMetaObject const * __thiscall Parent

我从 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)

s
sayyed mohsen zahraee

您应该删除应用程序的 debug 文件夹并再次运行它以更正此问题。


我有同样的问题。删除调试文件夹没有帮助。还有什么想法吗?
@Vern Jensen,检查 Q_OBJECT 宏,然后重建,然后删除调试/发布文件夹(以删除所有 moc 文件)并再次重建。其中之一应该会有所帮助。
使用 VS 2012 的 QT5 插件时,从类中删除 Q_OBJECT 宏,保存并添加 Q_OBJECT 再次对我有用
这也解决了我的问题。但为什么以及如何?任何人请解释一下。谢谢!
我在课堂项目中遇到了同样的问题。我发现完全删除 Q_OBJECT 宏解决了我的问题。不知道为什么。但如果我把它放回去,我会收到同样的 3 个未解决的错误。我通过在 QT 的 .pro 文件和我正在使用的 cmakelists.txt 文件中包含新类来解决这个问题。一旦我包含了标头和 cpp 文件,代码就可以使用 QObject
M
Melebius

如果您使用的是 Visual Studio,请从头文件中删除行 Q_OBJECT,保存文件,将 Q_OBJECT 放回头文件,再次保存文件。这应该会生成 moc_* 文件并且应该正确构建和链接。


其他解决方案都不适合我,但确实如此!谢谢! ;)
如果您使用的是 CMake,请确保您有 set(CMAKE_AUTOMOC ON)
这个答案也应该被认为是一个有效的答案!
适合我(VS2017),谢谢。编译时注释掉“Q_OBJECT”,如果恢复则不编译。不会激发对 Qt 的信心。我认为“Q_OBJECT”宏是必要的?
我也使用 VS 2017。以下发生在我身上:我将 AUTOMOC 添加到我的 CMakeLists 中。这使我的编译器在 public signal: 上窒息,这是以前没有的。尽管如此,每当代码中出现 Q_OBJECT 时,我都会遇到链接器错误,并且运行时错误表明我的自定义类未定义其他类型。
S
Stephen Quan

我注意到一些答案是基于 Visual Studio 的。

这个答案基于 Qt Creator。

与名称所暗示的不同,Rebuild Project 不会清除所有内容并从头开始构建。如果您最近将 QObject(和/或 Q_OBJECT)添加到您的课程中,则必须再次运行 qmake,例如

清理项目运行 qmake 构建项目

这是因为,默认情况下,qmake 仅在您对解决方案进行重大更改(例如添加新源文件或修改 .pro 文件)时运行。如果您对现有文件进行编辑,它不知道它需要运行 qmake

作为后备,要强制 Qt 从头开始构建所有内容,请删除 DebugRelease 文件夹。


杰出的!为我工作。 “运行 qmake”是关键步骤。如果要使用插槽,Q_OBJECT 是必需的。
V
Vern Jensen

所以问题是我需要 Qt MOC 编译器来编译我的 .h 文件。这对于扩展 QObject 或其子之一的任何类都是必需的。修复涉及(对我而言)右键单击头文件,选择属性,并将项目类型设置为“Qt MOC 输入”,然后在头上点击“编译”,然后将生成的 moc_myfilename.cpp 文件添加到我的项目。


这是在 XCode 中,右键单击“导航器”视图中列出的文件(项目使用的文件列表)。
这在 Visual Studio 中也是可能的,但其他人必须告诉你如何在那里配置它。 (我相信你可以在 Qt 的网站上找到答案。)
对于傻笑,我添加了一个头文件和一个 .cpp 文件并将我的 QtObject 派生类移到其中,然后还必须在头文件中 #include 并且突然它起作用了。这些东西真的应该记录在某个地方......
为我工作,除了类型是“自定义构建工具”而不是“Qt MOC 输入”。我正在使用 Visual Studio 2017。
在 VS 2019 上,它被称为 "Qt Meta-Object Compiler (moc)",当我更改它时对我有用。
V
Vinoj John Hosan

我手动将 cpp/ui 文件添加到我的项目中,但忘记将头文件显式添加为头文件。现在,在编译时,我收到了与上面类似的错误消息,并且 moc_*.cpp 文件未在构建的调试(或发布)目录中生成。这不是一个明显的错误,qmake 没有抱怨,除了链接器消息之外我没有收到任何错误。

因此,如果有人再次遇到同样的问题(或犯同样的复制和粘贴错误):确保头文件也已添加到您的项目文件中


A
Akın Yılmaz

如果您的 moc 文件是在 Visual Studio 项目中生成的,请尝试将它们包含到项目中,如果它们未包含在项目中,则重新构建。


为什么有必要这样做?
由于 VS 的一些错误配置阻止了 moc 文件的使用。有时即使它正确生成了 moc 文件但因为它们不包含在内,它的行为就像它不存在一样
T
Trevor Hickey

我在 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_FINDEBUG_FINEDH=7 "-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_%(Filename).cpp 将“附加依赖项”设置为:$(QTDIR)\bin\moc.exe;%(FullPath)

您的确切值可能不同。它们通常通过 Qt 插件应用。


为我工作,除了我可以在第一组 1、2、3 步后停下来;自定义构建工具配置可能已经在某处定义。我正在使用 Visual Studio 2017。
E
Edward

当我的 cpp 文件中有 Q_OBJECT 类定义时,我在 Visual Studio 2012 中遇到了这个问题。将类定义移动到头文件解决了这个问题。

看起来应该可以通过将 cpp 文件添加到 moc 来支持 cpp 文件中的 Q_OBJECT 类,但我没有尝试过。


这也是我的问题。不过,不得不在头文件中公开一个内部类很烦人。
w
whatnick

我使用 CMake 来管理 Qt 项目,并且需要在 QT4_WRAP_CPP 调用下添加新的 Q_OBJECT。这将生成 moc_*.cxx 以包含在项目中并清理未解析的外部。


D
Darkproduct

我的问题是我的一个使用 Qt 宏的文件没有被 moc'ed。我发现用于 Visual Studio 的 Qt 插件无法识别 Q_NAMESPACE 宏,因此不会将文件添加到 moc'ing 列表中。

所以我使用 this answer 中的解决方案将文件添加到麦克风列表:

您应该找到一个成功生成“moc_*”的.h文件,并将“自定义构建工具->常规”中的所有内容复制到新的.h文件设置页面。

请注意 DebugRelease-Mode 的不同选项。

之后,构建您的项目。

DebugRelease-Mode 中各构建一次

最后,将生成的“moc_*”文件添加到您的项目中。

现在,“moc_filename.cpp”应该在 Generated Files\DebugGenerated Files\Release 中。

右键单击它们中的每一个并更改它们的属性:

Debug 中的文件:将配置更改为 Release,然后将 General->Excluded 从 build 更改为 yes。

Release 中的文件:将配置更改为 Debug,然后将 General->Excluded 从 build 更改为 yes。


这是一个被低估的答案
P
Pugsley

在链式 CMake 目标的情况下面临此问题。事实证明,即使在不直接(传递)使用 Qt 的目标中,我也必须启用 CMAKE_AUTOMOC。还发现 CMAKE_AUTOMOC 不能在没有 find_package(QtX) 的情况下在父级的同一 CMakeLists.txtCMakeLists.txt 中使用。


d
dianull

就我而言(将 QtAdd-in 与 VS2012 和 Qt v4.8.4 一起使用),上述建议均无效。由于某种原因,VS 无法生成正确的 moc 文件(构建输出:未找到相关类。未生成输出。)当我手动编译相关头文件(将 qt moc 设置为编译器并单击“编译”)时,它产生了空 moc 文件.

起作用的是从命令行(moc -o moc_SomeClass.cpp SomeClass.h)编译所有必要的 mocs,然后在 GeneratedFiles 文件夹中替换错误的 mocs。

这只是成功构建项目的解决方法(对于大型项目来说不是一种方便的方法),但并不能真正解释奇怪的 VS/QtAdd-in 行为。


z
zengaja

将 QtAdd-in 与 VS2010 一起使用,我意识到 moc_*.cpp 文件已在 GeneratedFiles/Debug 文件夹中更新,尽管我处于发布模式。将文件复制到 Release 文件夹对我有用。


B
Brutus

我知道这是一个非常古老的问题,但它似乎仍然很有趣(过去几个月我至少来过这里 4 或 5 次)并且似乎我找到了另一个可能导致此错误的原因。

在我的头文件中,我输入错误:

#include "MyClass.h""

只有在检查了整个输出之后,我才发现编译器在那一行发出了警告。

现在我删除了额外的引号,我的 QObject 可以完美编译!


好笑!同样的错误在这里!!!刚去掉多余的引号,编译成功!
B
BuvinJ

在使用“PIMPL”(私有实现)编程模式时,我在 Qt 中使用“私有类”时遇到了这个问题。 Qt 在整个源代码中都使用了这个模型。我自己已经非常喜欢它了。

这种技术涉及在公共头文件中使用“私有”前向声明的类,该类将被“公共”类(即它的“父”)使用。然后父级有一个指向私有类实例的指针作为数据成员。

“私有”类完全在公共类的 cpp 文件中定义。私有类没有头文件。

所有“肮脏的工作”都是通过该私人课程完成的。这隐藏了公共类的所有实现,通常包括所有其他私有成员(数据和函数)。

我强烈建议您学习 PIMPL 模式——尤其是如果您要阅读内部 Qt 源代码。

在不进一步解释该编码风格的情况下,这里是与此问题相关的要点...要使 Q_OBJECT 宏在 cpp 内工作,以使“私有”类成为可以使用信号/插槽等的 QObject,< strong>您需要将 .moc 明确包含在 cpp 中的公共类中:

#include "MyPublicClass.moc"

您可以忽略有关此行的任何 IDE 警告。

我不确定它是否完全重要,但我总是看到在私有类定义之后完成的包含,而不是在 cpp 的顶部(就像通常放置的包含一样)。因此,cpp 布局如下所示:

“正常”包括已定义。定义了私有类。公共类的 moc 是#included。定义了公共类实现。


a
ashrasmun

视觉工作室 2017。

我已将文件添加到已设置 Qt 项目并收到此错误。我如何修复它:

右键单击解决方案资源管理器属性中的标题... -> 配置属性 -> 常规 -> 项目类型从 C/C++ 标题更改为 Qt 元对象编译器(moc)

瞧:)


p
phyatt

我最近从 MingW 切换到 MSVC 时发生了这种情况。我有一个原型类/结构列为类,MingW 不介意。

当涉及到原型设计时,MSVC 肯定会发现 classstruct 之间的区别。

希望有一天能帮助别人。


z
zar

就我而言,上述方法均无效,但这完全是我的错误。

我在 .h 文件中覆盖了虚函数(声明了它们),但从未在 .cpp 中定义它们 :)


N
Nadjib Dz

我通过将其添加到我的头文件中解决了我的问题:

#ifndef MYCLASSNAME_H
#define MYCLASSNAME_H

... // all the header file content.

#endif

A
Adam Woo

在 VS 2013 环境中,任何一个答案都适用于我。我最终通过从项目中删除 .h/.cpp 并将其添加回来来解决问题。


F
Flot2011

我正在使用集成的 Perforce p4v 客户端在 VS2015 中工作。就我而言,Perforce 尝试将 moc 文件添加到 depo,当我恢复此操作时,Perforce 从项目中删除了这个 moc 文件并将其删除。该文件在下一次编译后重新创建,但它没有包含在项目中,我必须手动将其添加到生成的文件中,当我终于明白问题出在哪里时。


J
Jefferson Rondan

我有同样的问题,我的解决方案是编码(我的带有“UTF16LE BOM”的文件不能用 moc.exe 生成),你创建另一个带有 ASCII 编码的文件并且它可以工作。

HxD HexEditor 可以帮助您查看编码。


S
Sanbrother

对我来说,这就是原因:QT的项目文件中没有包含一些头文件或源文件


b
burnack

在我的情况下,我在项目的子文件夹中有问题 QObject 祖先的 .h 和 .cpp 文件。当我将它们移到 CMakeLists.txt(项目根文件夹)旁边时,它成功链接。我可能缺少一些 CMake 命令来在子目录中包含 mocs fot 文件。


i
isudfv

当我删除 Q_OBJECT 它工作正常。

我正在使用 Clion + CMake + MSVC/14.31.31103。

是因为在这些之后不再需要 Q_OBJECT 吗?

set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)

关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅