QT踩坑记录1-Q_OBJECT编译问题
错误输出
Q_OBJECT
宏错误的地方会编译出现这样的错误, 无法找到....
由于自己不想再看到这个错误, 此处 复制自 参考连接1, 主要是连接错误 LNK2001
,
1>LoginDlg.obj : error LNK2001: 无法解析的外部符号 "public: virtual struct QMetaObject const * __thiscall CLoginDlg::metaObject(void)const " (? metaObject@CLoginDlg@@UBEPBUQMetaObject@@XZ)
1>LoginDlg.obj : error LNK2001: 无法解析的外部符号 "public: virtual void * __thiscall CLoginDlg::qt_metacast(char const *)" (?qt_metacast@CLoginDlg@@UAEPAXPBD@Z)
1>LoginDlg.obj : error LNK2001: 无法解析的外部符号 "public: virtual int __thiscall CLoginDlg::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@CLoginDlg@@UAEHW4Call@QMetaObject@@HPAPAX@Z)
1>D:VC++QtTMyDialog\MyDialog.exe : fatal error LNK1120: 3 个无法解析的外部命令
介绍
首先看一下一个基本的 QT 类的简单实现, 继承自 QObject
, 然后定义了 一个信号 signals_dosomething
和 一个槽函数 slots_dosomething
,
信号函数不用去实现, 只需要 设定与相应的函数进行连接即可, 即 使用 QObject::connect
连接, 且信号函数与槽函数的参数一致, 信号这里的连接与函数参数也是一个坑, 后续会更新相应的章节, 那类中 最开始 的地方 为什么要有一个 宏 Q_OBJECT
这里可以参考 QT Q_OBJECT, 里面做了详细的解释
#include <QObject>
class MyClass:public QObject
{
Q_OBJECT
signals:
void signals_dosomething(int n);
public slots:
void slots_dosomething(int n)
{
m_value_ = n;
}
private:
int m_value_;
public:
MyClass(QObjet *parent = nullptr)
:QObject(parent),
m_value_(0)
{
QObject::connect(this,
&MyClass::signals_dosomething,
this,
&MyClass::slots_dosomething,
Qt::DirectConnection);
}
}
解决
由于本人使用的是QT构建工程,然后使用 VS 的 QT VS Tools
将QT 工程转生成的 VS 工程,
存在各种问题,甚至出现 QT编译通过 VS 编译不通过的问题, 这里使用最暴力的方式, 直接使用 QT 的 moc
命令 将相应 类的声明 h 文件 moc 成cpp 文件,
moc MyClass.h -o moc_MyClass.cpp
然后将cpp 文件放置到相应的生成目录下面即可, 一般在 解决方案/工程/debug 下面,里面全是 moc_* 的cpp 文件和 obj 文件
注意查找自己的目录下面即可, 在手动 moc 生成之后, 之前编译不通过的 VS工程也编译通过了,
这里猜想是,
利用Qt编程时,写好.h、.cpp文件并第一次编译之后,若.h文件中定义类时没有添加Q_OBJECT宏以及信号函数、槽函数,VS编译命令中就没有moc命令,就不会调用Qt的moc工具以生成moc_*.cpp文件;并且即使添加了Q_OBJECT宏之后,VS也不会自动添加moc命令,因而不会生成moc文件。
VS在LINK时,找不到moc文件,就出现了error LNK2001的错误。