【问题标题】:Qt, VS2005, Qwt - Can't use Q_OBJECT in class derived from Qwt widgetsQt、VS2005、Qwt - 不能在派生自 Qwt 小部件的类中使用 Q_OBJECT
【发布时间】:2010-01-07 17:17:55
【问题描述】:

我们已经为 VS2005 编译了 QT 4.6 和 QWT 5.2.0。

我们试图从 QwtDial 派生一个类,而派生类有插槽。所以,我们需要添加 Q_OBJECT 宏。但是,当我们这样做时,链接器会消除此错误:

错误 LNK2001:无法解析的外部符号“public: static struct QMetaObject const QwtDial::staticMetaObject”(?staticMetaObject@QwtDial@@2UQMetaObject@@B)

我查看了带有depends 的Qwt.dll,它具有该功能。使用十六进制编辑器查看 .lib 文件会发现它与该名称损坏的字符串完全匹配。

我们在路径中有 Qwt 库。实际上,如果我重命名 lib,那么它会给出一个错误,即找不到 lib 文件。所以,我们知道它正在寻找正确的库。

如果我们跳过 Q_OBJECT,那么一切都使用几个 QWT 小部件正确链接和绘制,包括我们的非 Q_OBJECT Qwt 派生类。

有谁知道什么会导致这个非常烦人的链接器问题?

更新:

我已经验证了我添加 Q_OBJECT 的类肯定会为它生成一个 MOC 文件。链接器错误实际上来自这个生成的 MOC 文件:

moc_GaugeWidget1.obj : error LNK2001: unresolved external symbol "public: static
    struct QMetaObject const QwtDial::staticMetaObject" 
    (?staticMetaObject@QwtDial@@2UQMetaObject@@B)

所以,它看起来很奇怪和不典型。该符号肯定在库中。

【问题讨论】:

    标签: qt visual-studio-2005 qt4 qwt


    【解决方案1】:

    我也有同样的问题。好吧,我正在使用 Qt4.4 和 VC2003 更新一个旧项目,并且我使用的是 QwtPlot 而不是 QwtDial。错误是:

    LNK2001:未解析的外部符号“public: static struct QMetaObject const QwtPlot::staticMetaObject”(?staticMetaObject@QwtPlot@@2UQMetaObject@@B)

    就是这样。没有其他的。我发现论坛参考指向调试/发布混淆问题,并且可能与删除 Qt Designer 插件有关。

    这似乎对我有用: 将行:“DEFINES += QWT_DLL”添加到 project.pro 文件的顶部。

    qmake 项目.pro

    nmake 发布

    【讨论】:

    • +1:谢谢,它有帮助!我认为,QWT 中缺少定义开关。类似于“如果在此库中使用,请将 QWT_DLL 设置为 Q_DECL_EXPORT,否则将 QWT_DLL 设置为空”。这就是为什么如果使用 QWT 标头,您应该手动将 QWT_DLL 设置为空。
    【解决方案2】:

    我不确定这个答案,但这里有一些信息:

    在我看来,您的派生类没有匹配的 moc_ 文件! moc 文件通常在使用 Q_OBJECT 宏时使用...您的项目的 moc 信息存储在 Makefile、Makefile.debug 和 Makefile.release 文件中!正是这个文件告诉了哪些 .cpp 文件需要 moc 文件,哪些不需要。

    您可以在 QtAssistant 中找到有关 moc 的文档:http://qt.nokia.com/doc/4.6/moc.html

    现在,要检查这一点,您需要进入“生成”文件夹并查找名为“moc_yourDerivedClass.cpp”的文件。

    如果你找不到任何匹配的文件,你需要通过你的派生类再次执行 qmake 过程...也许当你第一次使用 qmake 时,Q_OBJECT 宏还没有在类中,因此没有 moc 文件已创建...

    希望对你有所帮助!

    【讨论】:

    • 我会建议你一些东西,它可能无法实现,但可能对未来项目有所帮助。我正在使用我的一个朋友开发的脚本包。你可以在这里找到它:dprog.net/joomla/… 设置它需要做一些工作,比如指定你正在使用哪个 VS,哪个 Qt 版本,你的 .PRO 文件在哪里等等......然后其他一切都是自动完成,添加新添加的文件,创建 .PRI 文件,vcproj 文件......真的很好......
    • 使用那个包,例如,当我添加一个文件时,我把它放在正确的文件夹中,在我的 .PRO 文件旁边。我启动了一个名为“generate_vcproj.bat”的脚本,脚本生成了所有内容......然后我使用“Launch_ide.bat”,我的 VS 启动了所有设置(moc 文件))
    • 至于这个答案,不......肯定有一个MOC文件。 (moc_GaugeWidget1.obj : error LNK2001: unresolved external symbol "public: static struct QMetaObject const QwtDial::staticMetaObject" (?staticMetaObject@QwtDial@@2UQMetaObject@@B)) ...所以,还有其他一些问题/错误正在发生。
    • moc_GaugeWidget1.obj 基于 moc_GaugeWidget.cpp,这是我添加 Q_OBJECT 的类的 MOC 文件。
    • 嘿,我找到了这个,也许它可以解决你的问题:“问题似乎是QT生成的moc文件。有两个版本,一个用于调试,一个用于发布. 在配置之间切换应该切换正确的文件, 这意味着两者中的一个总是从构建中排除. 如果文件混淆了, 例如在构建调试时包含了一些用于发布的 moc 文件, 文件被编译但可以不能链接,因为是错误的配置......”
    【解决方案3】:

    问题出在 moc 文件上。你应该在 QwtPlot 定义中使用 Q_DECL_EXPORT(或其他类似的东西)告诉编译器这个类可以被其他库使用,但是在 moc 文件中生成的类的部分不包含这些所以当您将这些库与其他程序链接时,它不知道如何链接这些部分。 无论如何,我不知道如何将这些告诉 Qt!

    【讨论】:

      【解决方案4】:

      这里的问题与 qwt 5.2.1、qt 4.6 和 VS2008 完全相同。相同的代码可以在 Linux 中完美编译。 所有 moc 文件均已正确生成和处理,没有发布/调试混合库,我将在有时间时将其报告给 qwt 错误。

      将 QWT_DLL 添加到定义列表(项目属性->c++->预处理器->定义)确实可以解决问题!

      【讨论】:

        【解决方案5】:

        尝试在项目目录中再次运行 qmake。

        $ qmake -project

        $ qmake -tp vc

        这就是为我解决问题的原因。阅读了很多人给出的“看起来你有 moc 文件问题”的解释,让我不知道该怎么办。

        我想我在这个问题上引起了我自己的问题。在构建整个项目之前,我右键单击并编译了项目中的 .ui 文件。不知何故,这并没有完全生成所需的所有文件。无论如何,如果您突然遇到以前没有的问题,运行 qmake 是一件很有用的事情。

        但是,我在项目设置中注意到另一件事,没有设置任何预处理器指令。再次运行 qmake 解决了这个问题。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-05-25
          • 1970-01-01
          相关资源
          最近更新 更多