现在的位置: 首页 > 综合 > 正文

qobject_cast 的一点感悟

2017年12月16日 ⁄ 综合 ⁄ 共 2343字 ⁄ 字号 评论关闭

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;
}

下面来分析四个label的返回值是不是0……

ui->label 指向 DetailInfoLabel*……

label1 : QLabel是 DetailInfoLabel父类,所以label1不为0;

label2 : QObject是DetailInfoLabel父类,所以label2不为0;

label3 : QWidget是DetailInfoLabel父类,所以label3不为0;

label4 : 同级,所以label4也不为0;但是编译的时候却出错了,提示void value not ignored as it ought to be.很是纳闷,经过检查原来是 DetailInfoLabel中没有Q_OBJECT定义。

果断加上,之后工程得qmake以下,不然仍会出错。

通过这个例子,更加了解到qobject_cast的用处。转换的时候首先得弄清楚obj究竟是什么,它指向谁,他的本质是什么,然后看转换的对象是什么类型,转换的对象类型必须是obj的父类或者同级才能得到正确的结果。同时还得注意Q_OBJECT宏定义。

抱歉!评论已关闭.