web-dev-qa-db-ja.com

Q_OBJECTはいつ使用する必要がありますか?

ドキュメントには、次のように記載されています。

Q_OBJECTマクロは、独自のシグナルとスロットを宣言するか、Qtのメタオブジェクトシステムによって提供される他のサービスを使用するクラス定義のプライベートセクションに表示する必要があります。

しかし正確にそれはどういう意味ですか?どのQObject派生クラスで安全に省略できますか? QObjectから派生したクラスでQ_OBJECTを省略し、そのクラスから継承すると問題が発生しますか?基本的に、Qtクラスからいつ省略できるかについて、もう少し情報が欲しいのですが。

47
Jake Petroules

_Q_OBJECT_マクロQObjectから派生するテンプレート化されていないクラスを使用する必要があります。

シグナルとスロットに加えて、_Q_OBJECT_マクロは、特定のクラスに関連付けられているメタオブジェクト情報を提供します。

ドキュメント で述べたように:

QObjectのすべてのサブクラスはQ_OBJECTマクロを使用するが実際に信号、スロット、プロパティを使用するかどうかに関係なく、強くお勧めします。

次のクラスがあるとします。

_class Class : public QObject {
public:
  Class() {}
};
_

_Q_OBJECT_がないと、次のメタオブジェクトシステム機能(特に)はClassでは機能しません。

  1. qobject_cast<Class>()-メタデータがないため

  2. QObject::tr()-メタデータがないため

  3. Classで最初に宣言されたスロットと呼び出し可能オブジェクトは、呼び出されるか名前で検索されると、これらのメソッドに対してQMetaObjectメソッドは機能せず、Qt 4 connectも機能しないメタデータがありません

  4. シグナル-mocはそれらの実装を生成せず、コードはコンパイルされません。

もちろん省略できますが、これらの機能を使用する場合は、マクロをクラスの宣言に含めることを忘れないでください。これはかなり脆弱な方法であり、回避することをお勧めします。節約はそれだけの価値はありません。だから待ってはいけません-コーディングポリシーの問題として、QObjectから派生するすべてのクラスに_Q_OBJECT_マクロを追加してください。

_Q_OBJECT_マクロは、QObjectから派生しないクラスではneverを使用しないでください。そのようなクラスに呼び出し可能オブジェクトとプロパティを追加するには、代わりに_Q_GADGET_マクロを使用します。

35
liaK

シグナル/スロットを使用したい場合は、Q_OBJECTマクロを含め、QObjectからクラスを派生させる必要があります。

それ以外の場合は省略できますが、すべてのQt guiクラスに含めても害はありません。

6
Martin Beckett

さて、おそらくすでにご存じのとおり、最初の部分はかなり明確です。シグナルとスロット、メタオブジェクトシステムの残りの部分は、あまり知られていません。おそらく、より便利な機能の1つは動的プロパティです。これらには多くの用途がありますが、QtのアニメーションシステムQPropertyAnimationを利用するために使用しました。

メタオブジェクトシステムに関するもう少し情報があります: http://doc.qt.io/archives/4.6/metaobjects.html

一番下の行は、QObject階層から継承する場合は関係なくQ_OBJECTマクロをスローすると思います。それは簡単で、将来の不可解な問題からあなたを救うでしょう。

4
Arnold Spence

@liaKの発言は正しいです(つまり、あなたは常にQObjectから派生するクラスでは常にQ_OBJECTマクロを使用する必要があります)。

ハイライト表示されていないのは、しないでください明示的にQ_OBJECTマクロは時々非常に便利なqobject_cast を使用しても機能しません!!!

2
lucabox