メタ・オブジェクト・システム

Qt のメタオブジェクトシステムは、オブジェクト間通信のためのシグナルとスロットのメカニズム、ランタイムの型情報、動的なプロパティシステムを提供します。

メタオブジェクトシステムは以下の3つに基づいています:

  1. QObject クラスは、メタ・オブジェクト・システムを利用できるオブジェクトの基本クラスを提供する。
  2. Q_OBJECT マクロは、動的プロパティ、シグナル、スロットなどのメタオブジェクト機能を有効にするために使用されます。
  3. マクロ Meta-Object Compiler(moc) は、各QObject サブクラスにメタオブジェクト機能を実装するために必要なコードを提供します。

moc ツールは C++ ソース・ファイルを読み込みます。Q_OBJECT マクロを含むクラス宣言が 1 つ以上見つかると、それらの各クラスのメタオブジェクト・コードを含む別の C++ ソース・ファイルを生成します。この生成されたソース・ファイルは、#include'dされてクラスのソース・ファイルに組み込まれるか、通常はコンパイルされてクラスの実装とリンクされます。

オブジェクト間の通信のためのシグナルとスロットのメカニズム(このシステムを導入した主な理由)を提供することに加えて、メタ・オブジェクト・コードは以下の追加機能を提供します:

また、QObject クラスに対してqobject_cast() を使用してダイナミック・キャストを行うことも可能です。qobject_cast() 関数の動作は、標準 C++ のdynamic_cast() と似ていますが、RTTI サポートが不要で、ダイナミック・ライブラリの境界を越えて動作するという利点があります。この関数は、角括弧で指定されたポインタ型に引数をキャストしようと試み、オブジェクトの型が正しければ(実行時に決定される)0以外のポインタを返し、オブジェクトの型が互換性がなければnullptr

例えば、MyWidgetQWidget を継承し、Q_OBJECT マクロで宣言されているとします:

    QObject *obj = new MyWidget;

QObject * 型の変数obj は、実際にはMyWidget オブジェクトを参照しているので、適切にキャストできます:

    QWidget *widget = qobject_cast<QWidget *>(obj);

オブジェクトは実際にはQWidget のサブクラスであるMyWidget であるため、QObject からQWidget へのキャストは成功する。objMyWidget であることがわかっているため、MyWidget * にもキャストできる:

    MyWidget *myWidget = qobject_cast<MyWidget *>(obj);

qobject_cast() は組み込み Qt 型とカスタム型を区別しないので、MyWidget へのキャストは成功します。

    QLabel *label = qobject_cast<QLabel *>(obj);
    // label is 0

一方、QLabel へのキャストは失敗します。これにより、異なる型のオブジェクトを、型に応じて実行時に異なるように扱うことができます:

    if (QLabel *label = qobject_cast<QLabel *>(obj)) {
        label->setText(tr("Ping"));
    } else if (QPushButton *button = qobject_cast<QPushButton *>(obj)) {
        button->setText(tr("Pong!"));
    }

Q_OBJECT 、メタ・オブジェクト・コードなしでQObject を基本クラスとして使用することは可能ですが、Q_OBJECT マクロを使用しない場合、シグナルとスロット、およびここで説明するその他の機能は使用できません。メタ・オブジェクト・システムから見ると、メタ・コードを持たないQObject サブクラスは、メタ・オブジェクト・コードを持つ最も近い祖先と同等です。これはたとえば、QMetaObject::className ()はあなたのクラスの実際の名前を返すのではなく、この祖先のクラス名を返すことを意味します。

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

QMetaObjectQtのプロパティシステムシグナルとスロットも参照してください

© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.