qobject_castの少しの悟り


T qobject_cast ( QObject * object )


Returns the given object cast to type T if the object is of type T (or of a subclass); otherwise returns 0. If object is 0 then it will also return 0.
The class T must inherit (directly or indirectly) QObject and be declared with the Q_OBJECT macro.
A class is considered to inherit itself.
Example:
 QObject *obj = new QTimer;          // QTimer inherits QObject

 QTimer *timer = qobject_cast<QTimer *>(obj);
 // timer == (QObject *)obj

 QAbstractButton *button = qobject_cast<QAbstractButton *>(obj);
 // button == 0

The qobject_cast() function behaves similarly to the standard C++ dynamic_cast(), with the advantages that it doesn't require RTTI support and it works across dynamic library boundaries.
qobject_cast() can also be used in conjunction with interfaces; see the Plug & Paint example for details.
Warning: If T isn't declared with the Q_OBJECT macro, this function's return value is undefined.
See also QObject::inherits().
これは公式文書で紹介されていますが、今日運用するときは間違いを除いて、新しい工事を作って、具体的にその役割を体得して、少し分かりました.
新しいプロジェクトを作成し、uiにlabelを追加し、クラスDetailInfoLabelを作成し、QLabelに継承します.
//detailinfolabel.h

#ifndef DETAILINFOLABEL_H
#define DETAILINFOLABEL_H

#include <QLabel>

class DetailInfoLabel : public QLabel
{
    Q_OBJECT
public:
    DetailInfoLabel(QWidget *parent = 0);

    void setDetailText(const QString &str);
};

#endif // DETAILINFOLABEL_H
//detailinfolabel.cpp

#include "detailinfolabel.h"
#include <QFont>
#include <QFontMetrics>

DetailInfoLabel::DetailInfoLabel(QWidget *parent)
    : QLabel(parent)
{
    //setWordWrap(true);
}

void DetailInfoLabel::setDetailText(const QString &str)
{
    QFont font;
    QFontMetrics fontMetrics(font);
    QString newStr = fontMetrics.elidedText(str, Qt::ElideMiddle, width());
    setText(newStr);
}
//widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QtGui>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    QLabel *label1 = qobject_cast<QLabel*>(ui->label);
    QObject *label2 = qobject_cast<QObject*>(ui->label);
    QWidget *label3 = qobject_cast<QWidget*>(ui->label);

    DetailInfoLabel *label4 = qobject_cast<DetailInfoLabel*>(ui->label);

}

Widget::~Widget()
{
    delete ui;
}

次に、4つのlabelの戻り値が0であるかどうかを分析します.
ui->labelはDetailInfoLabel*を指しています.
Label 1:QLabelはDetailInfoLabelの親であるため、label 1は0ではありません.
Label 2:QObjectはDetailInfoLabelの親であるため、label 2は0ではありません.
Label 3:QWidgetはDetailInfoLabelの親であるため、label 3は0ではありません.
Label 4:同級なので、label 4も0ではありません.しかしコンパイル中にエラーが発生し、void value not ignored as it ought to be.とても気がふさいで、検査を経てもとはDetailInfoLabelの中でQ_がありませんでしたOBJECT定義.
思い切って加えて、後で工事はqmake以下になって、さもなくば依然として間違いがあります.
この例を通して、qobject_をさらに理解します.castの使い道.変換するときはまずobjが何なのか、それが誰を指しているのか、彼の本質が何なのかを明らかにし、変換されたオブジェクトがどんなタイプなのかを見て、変換されたオブジェクトのタイプはobjの親または同級でなければ正しい結果を得ることができません.同時にQ_にも注意しなければなりませんOBJECTマクロ定義.