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++\QtT\MyDialog\\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的錯誤。
