QT error LNK2001: 无法解析的外部符号 "public: virtual struct QMetaObject const * __thiscall Widget::metaObjec

来源:互联网 发布:js产生1到3随机数 编辑:程序博客网 时间:2024/05/17 10:39

因为QT槽的问题,导致构建过程中报错:

原因:只有继承了QObject类的类,才具有信号槽的能力。所以,为了使用信号槽,必须继承QObject。凡是QObject类(不管是直接子类还是间接子类),都应该在第一行代码写上Q_OBJECT。不管是不是使用信号槽,都应该添加这个宏。这个宏的展开将为我们的类提供信号槽机制、国际化机制以及 Qt 提供的不基于 C++ RTTI 的反射能力。因此,如果你觉得你的类不需要使用信号槽,就不添加这个宏,就是错误的。其它很多操作都会依赖于这个宏。注意,这个宏将由 moc(我们会在后面章节中介绍 moc。这里你可以将其理解为一种预处理器,是比 C++ 预处理器更早执行的预处理器。)做特殊处理,不仅仅是宏展开这么简单。moc 会读取标记了 Q_OBJECT 的头文件,生成以 moc_ 为前缀的文件,比如 newspaper.h 将生成 moc_newspaper.cpp。你可以到构建目录查看这个文件,看看到底增加了什么内容。注意,由于 moc 只处理头文件中的标记了Q_OBJECT的类声明,不会处理 cpp 文件中的类似声明。因此,如果我们的NewspaperReader类位于 main.cpp 中,是无法得到 moc 的处理的。解决方法是,我们手动调用 moc 工具处理 main.cpp,并且将 main.cpp 中的#include "newspaper.h"改为#include "moc_newspaper.h"就可以了。不过,这是相当繁琐的步骤,为了避免这样修改,我们还是将其放在头文件中。许多初学者会遇到莫名其妙的错误,一加上Q_OBJECT就出错,很大一部分是因为没有注意到这个宏应该放在头文件中。

https://www.devbean.net/2012/08/qt-study-road-2-custom-signal-slot/


网上类似问题统计:

http://bbs.csdn.net/topics/390732465

http://blog.csdn.net/zhenyusoso/article/details/8450906


手动生成moc文件方法:

Qt 程序在交由标准编译器编译之前,先要使用 moc 分析 C++ 源文件。如果它发现在一个头文件中包含了宏 Q_OBJECT,则会生成另外一个 C++ 源文件。这个源文件中包含了 Q_OBJECT 宏的实现代码。这个新的文件名字将会是原文件名前面加上 moc_ 构成。这个新的文件同样将进入编译系统,最终被链接到二进制代码中去。因此我们可以知道,这个新的文件不是“替换”掉旧的文件,而是与原文件一起参与编译。


   vs2010集成Qt后,编译无法生成moc文件,此时可以采用手动方式生成:

在命令行下输入moc yourfilename.h -o moc_youfilename.cpp生成不带Q_OBJENT的源文件。


 下面给出例子手动生成moc的例子:

 
1、首先在运行窗口中输入cmd
[Qt]vs2010中moc文件生成方法(含有截图)

2、在cmd中输入:cd  C:\Qt\4.7.4\bin进入Qt安装目录,如下图:
[Qt]vs2010中moc文件生成方法(含有截图)

3、输入:moc "E:\03 Code\QUnitTest\DlgFindDialog.h" -o "E:\03 Code\QUnitT
est\moc_DlgFindDialog.cpp" 后回车
[Qt]vs2010中moc文件生成方法(含有截图)

4、打开E:\03 Code\QUnitTest,moc_DlgFindDialog.cpp已经生成

[Qt]vs2010中moc文件生成方法(含有截图)

5、到此moc文件已经生成完毕。

http://blog.sina.com.cn/s/blog_a459dcf50101ded1.html


VS中解决参考:

使用QWT例子oscilloscope出现如下错误:


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

 本来这个例子在examples文件下直接QtCreator打开pro运行无错的。

当我转到VS项目里就无法编译通过,原来是Qwt在pri文件里定义了一个

win32 {
    contains(QWT_CONFIG, QwtDll) {
        DEFINES    += QT_DLL QWT_DLL
    }
}


所以在VS项目里,我们也需要设置一个预处理QWT_DLL。只有在预处理的时候定义了 QWT_DLL才能使用QWT的抛出类,否则就会出错!这个道理同样适用于我们自己生成的动态库,VS2008中的设置方法如下图所示:


 

具体方法:请看下面

 

------------------------------------转载------------------------------------------

在使用QWT进行二维曲线绘制,使用方法如下:

class Plotpublic QwtPlot

{

   Q_OBJECT

……

}

此时报错:error LNK2001: 无法解析的外部符号"public: static struct QMetaObject const QwtPlot::staticMetaObject"

出现这样的连接错误一般都是由于QwtPlot类的头文件中没有加Q_OBJECT而导致的,QwtPlot是QWT提供的类,怎么可能没有加Q_OBJECT宏呢?好吧,那就老老实实的跟踪打开QwtPlot类的头文件看看吧(没法查看QwtPlot的.cpp文件,应为QWT通过动态库的方式提供这些类的)

class QWT_EXPORT QwtPlotpublic QFramepublic QwtPlotDict

{

    Q_OBJECT

……

}

       我晕!QwtPlot类加宏Q_OBJECT了,那为什么还会出现这个连接错误?这是什么原因?QWT已经是非常成熟的QT关于二维曲线绘制的开源框架了,也不可能会出现这样的低级错误。算了,换种使用方法试试吧:

class Plotpublic QwtPlot

{

  //Q_OBJECT

……

}

       注销掉派生类中的Q_OBJEXT,疯了。居然编译通过了!这又是什么原因?OK!我已无能为力,还是交给高手吧!……!五分钟后,高手回复了(不愧是高手)!

       由于预处理所带来的问题

       QWT通过动态库抛出类的方式将类QwtPlot抛出供使用者使用,我们来看一下抛出地方时如何定义的(位于qwt_golbal.h):

#ifdef QWT_DLL

#if defined(QWT_MAKEDLL)     // create a Qwt DLL library

#define QWT_EXPORT  __declspec(dllexport)

#define QWT_TEMPLATEDLL

#else                        // use a Qwt DLL library

#define QWT_EXPORT  __declspec(dllimport)

#endif

#endif // QWT_DLL

    我们应该怎么理解上面这段代码呢?只有在预处理的时候定义了 QWT_DLL才能使用QWT的抛出类,否则就会出错!这个道理同样适用于我们自己生成的动态库,VS2008中的设置方法如下图所示:



http://qimo601.iteye.com/blog/1457211

0 0
原创粉丝点击