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)
この問題を修正するには、アプリケーションのdebug
フォルダーを削除し、再度実行する必要があります。
Visual Studioを使用している場合は、Q_OBJECT
ヘッダーファイルから、ファイルを保存し、Q_OBJECT
ヘッダーファイルに戻り、ファイルを再度保存します。これにより、moc_*
ファイルを作成し、正しくビルドしてリンクする必要があります。
いくつかの答えはVisual Studioに基づいていることに気付きました。
この回答はQt Creatorに基づいています。
名前とは異なり、Rebuild Project
は、すべてを消去してゼロから構築するわけではありません。クラスにQObject
(および/またはQ_OBJECT)を最近追加した場合は、qmake
を再度実行する必要があります。
これは、デフォルトでは、qmake
が実行されるのは、新しいソースファイルを追加したり、.pro
ファイル。既存のファイルを編集した場合、qmake
を実行する必要があることはわかりません。
フォールバックとして、Qtをブルートフォースですべてをゼロから構築するには、Debug
またはRelease
フォルダーを削除します。
そのため、問題は.hファイルをコンパイルするためにQt MOCコンパイラが必要だったことです。これは、QObjectまたはその子の1つを拡張するクラスに必要です。修正には(私にとって)ヘッダーファイルを右クリックして[プロパティ]を選択し、アイテムタイプを[Qt MOC Input]に設定し、ヘッダーで[Compile]を押して、結果のmoc_myfilename.cppファイルをmy事業。
Visual Studioプロジェクトでmocファイルが生成された場合、それらがプロジェクトに含まれていない場合はプロジェクトに含めてから再構築してください。
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_NET_WORK -DWIN32_LEAN_AND_MEAN -DDIS_VERSION = 7 -D_MATH_DEFINES_DEFINED "-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プラグインを介して適用されます。
CMakeを使用してQtプロジェクトを管理し、QT4_WRAP_CPP呼び出しの下に新しいQ_OBJECTを追加する必要があります。これにより、プロジェクトに含めるmoc _ *。cxxが生成され、未解決の外部がクリーンアップされます。
CppファイルにQ_OBJECTクラス定義があると、Visual Studio 2012でこの問題が発生しました。クラス定義をヘッダーファイルに移動すると、問題が解決しました。
Mocにcppファイルを追加することで、cppファイルでQ_OBJECTクラスをサポートできるように見えますが、私はこれを試しませんでした。
プロジェクトにcpp/uiファイルを手動で追加しましたが、ヘッダーファイルをヘッダーファイルとして明示的に追加するのを忘れていました。コンパイル時に、上記と同様のエラーメッセージが表示され、ビルドのデバッグ(またはリリース)ディレクトリにmoc _ *。cppファイルが生成されませんでした。それはそれほど明白な間違いではなく、qmakeは文句を言わず、リンカーメッセージ以外にエラーはありませんでした。
だから誰かが再び同じ問題に出くわした場合(または同じコピーと間違えた場合):ヘッダーファイルもプロジェクトファイルに追加されていることを確認してください
私の問題は、Qtマクロを使用していたファイルの1つがmocされていないことでした。 Qt Plugin for Visual StudioはQ_NAMESPACE
マクロを認識しないため、ファイルをmoc'ingリストに追加しないことがわかりました。
そのため、 this answer のソリューションを使用して、ファイルをマイキングリストに追加しました。
「moc_ *」を正常に生成した.hファイルを見つけ、「Custom Build Tool-> General」のすべての内容を新しい.hファイル設定ページにコピーします。
Debug
とRelease
- Modeの異なるオプションに注意してください。
その後、プロジェクトをビルドします。
Debug
およびRelease
- Modeでそれぞれ1回ビルドします
最後に、生成された「moc_ *」ファイルをプロジェクトに追加します。
これで、「moc_filename.cpp」はGenerated Files\Debug
およびGenerated Files\Release
にあるはずです。
それぞれを右クリックして、ヘアプロパティを変更します。
Debug
のファイル:構成をRelease
に変更してから、General->Excluded from build
をyes
に変更します。Release
のファイル:構成をDebug
に変更してから、General->Excluded from build
をyes
に変更します。私の場合(VS2012およびQt v4.8.4でQtAdd-inを使用)、上記の提案はいずれも機能しませんでした。何らかの理由でVSは適切なmocファイルを生成できませんでした(ビルド出力:関連するクラスが見つかりません。出力は生成されませんでした)。 。
動作したのは、必要なすべてのmocsをコマンドライン(moc -o moc_SomeClass.cpp SomeClass.h)からコンパイルし、GeneratedFilesフォルダー内の間違ったmocsを置き換えることでした。
これは、プロジェクトを正常にビルドするための回避策であり(大きなプロジェクトには便利ではありません)、実際には奇妙なVS/QtAdd-inの動作を説明するものではありません。
QtAdd-inをVS2010で使用すると、moc _ *。cppファイルがGeneratedFiles/Debugフォルダーで更新されていることに気付きましたが、私はリリースモードでした。ファイルをReleaseフォルダーにコピーするとうまくいきました。
「[〜#〜] pimpl [〜#〜] "(プライベート実装)プログラミングパターンを使用するときにQtで「プライベートクラス」を使用すると、この問題が発生しました。 Qtはソースコード全体でこのモデルを使用します。私は自分でそれを本当に好きになりました。
この手法では、パブリックヘッダーファイルで「プライベート」前方宣言クラスを使用します。これは、「パブリック」クラス(つまり「親」)によって使用されます。親は、データメンバーとしてプライベートクラスのインスタンスへのポインターを持ちます。
「プライベート」クラスは、パブリッククラスのcppファイル内で完全に定義されます。プライベートクラス用のヘッダーファイルはありません。
「汚い仕事」のすべては、そのプライベートクラスで行われます。これにより、他のすべてのプライベートメンバー(データと関数の両方)を含むパブリッククラスのすべての実装が非表示になります。
特に内部Qtソースを読む予定がある場合は、PIMPLパターンについて学ぶことを強くお勧めします。
そのコーディングスタイルをさらに説明することなく、この質問に関連するポイントを以下に示します... Q_OBJECT
マクロは、シグナル/スロットなどを使用できるQObjectである「プライベート」クラスのcpp内で動作します。cpp内のパブリッククラスに.mocを明示的に含める必要があります:
#include "MyPublicClass.moc"
この行に関するIDE警告は無視できます。
それがまったく手に負えないかどうかはわかりませんが、そのインクルードは、cppの最上部ではなく、プライベートクラス定義の後に行われます(インクルードが通常配置されるように)。したがって、cppレイアウトは次のようになります。
どちらの答えも、VS 2013環境で機能します。最終的に、プロジェクトから。h /。cppを削除し、追加し直すことで問題を解決しました。
これは最近、MingWからMSVCに切り替えたときに起こりました。クラスとしてリストされたプロトタイプのクラス/構造がありましたが、MingWは気にしませんでした。
MSVCは、プロトタイピングに関して、class
とstruct
の違いを明確に認識しています。
それがいつか他の誰かを助けることを願っています。
私にとって、これが原因です:QTのプロジェクトファイルに含まれていないヘッダーまたはソースファイル
私はこれが非常に古い質問であることを知っていますが、それはまだ興味深いようです(私は最後の月に少なくとも4〜5回ここにいました)、このエラーを得ることができる別の理由を見つけたようです。
私の場合、ヘッダーファイルに間違って入力しました:
#include "MyClass.h""
出力全体を調べて初めて、その行でコンパイラが警告を発していることがわかりました。
追加の引用符を削除したので、QObjectは完全にコンパイルされます!
私の場合、上記のいずれも機能しませんでしたが、それは完全に私の間違いでした。
.hファイルの仮想関数をオーバーライドしました(宣言しました)が、.cppでそれらを定義したことはありませんでした:)
私は同じ問題を抱えています、私の解決策はエンコーディングでした(「UTF16LE BOM」のファイルはmoc.exeで生成できません)、y ASCII encondingで別のファイルを作成して動作します。
HxD HexEditorは、体系化を確認するのに役立ちます。
これをヘッダーファイルに追加して問題を解決しました。
#ifndef MYCLASSNAME_H
#define MYCLASSNAME_H
... // all the header file content.
#endif
VS2015で統合されたPerforce p4vクライアントを使用しています。私の場合、Perforceはmocファイルをデポに追加しようとしましたが、この操作を元に戻すと、Perforceはこのmocファイルをプロジェクトから削除して削除しました。ファイルは次のコンパイル後に再作成されましたが、プロジェクトに含まれていませんでした。生成されたファイルに手動で追加する必要があります。