简体   繁体   English

QVariant :: isNull()和自定义类型

[英]QVariant::isNull() and custom type

Can I somehow use QVariant::isNull() with a custom Q_DECLARE_METATYPE() type? 我可以以某种方式使用QVariant::isNull()与自定义Q_DECLARE_METATYPE()类型?

For example, if I define such a wrapper class for an integer (why should I, but this should be a minimal example). 例如,如果我为一个整数定义这样一个包装类(我为什么要这样做,但这应该是一个最小的例子)。 Defining a bool isNull() const member function doesn't help: 定义bool isNull() const成员函数没有帮助:

#include <QVariant>
#include <QDebug>

class Integer {
    bool null;
    int x;
public:
    Integer() : null(true), x(0) {}
    Integer(int x) : null(false), x(x) {}
    int value() const {
        return x;
    }
    bool isNull() const {
        return null;
    }
};
Q_DECLARE_METATYPE(Integer)

int main()
{
    Integer x(42);
    Integer y(0);
    Integer z;

    qDebug() << x.isNull() << QVariant::fromValue(x).isNull();
    qDebug() << y.isNull() << QVariant::fromValue(y).isNull();
    qDebug() << z.isNull() << QVariant::fromValue(z).isNull(); // Not as expected!
}

Output: 输出:

false false 
false false 
true false     // Not as expected!

Unfortunately you can't. 不幸的是你不能。 The QVariant::isNull code is the following: QVariant::isNull代码如下:

static bool isNull(const QVariant::Private *d)
{
    switch(d->type) {
    case QVariant::String:
        return v_cast<QString>(d)->isNull();
    case QVariant::Char:
        return v_cast<QChar>(d)->isNull();
    case QVariant::Date:
        return v_cast<QDate>(d)->isNull();
    case QVariant::Time:
        return v_cast<QTime>(d)->isNull();
    ...
    }
    return d->is_null;
}

As you can see it explicitely uses the isNull() function of some common variable types and by default it returns the d->is_null value. 正如您所看到的,它明确地使用了一些常见变量类型的isNull()函数,默认情况下它返回d->is_null值。

The d->is_null is a class member of the D pointer of the QVariant class which is initialized to true but every time you assign a value to the QVariant it becomes false : d->is_nullQVariant类的D指针的类成员,它初始化为true但每次为QVariant赋值时,它都变为false

inline void qVariantSetValue(QVariant &v, const T &t)
{
    ...
    d.is_null = false;
    ...
}

So for custom types it will always return false . 因此对于自定义类型,它将始终返回false

One possibility ( which I do not recommend ) would be to subclass QVariant and reimplement the isNull function. 一种可能性( 我不推荐 )是子类QVariant并重新实现isNull函数。 In this function you could check if the type is custom and in this case you can return the return value of the isNull function of your custom class, otherwise you should return the return value of the QVariant::isNull function. 在此函数中,您可以检查类型是否为自定义,在这种情况下,您可以返回自定义类的isNull函数的返回值,否则您应该返回QVariant::isNull函数的返回值。

bool MyQVariant::isNull() const
{
    if (QString(typeName()) == "MyCustomClass")
       return value<MyCustomClass>().isNull();
    return QVariant::isNull();   
}

EDIT 编辑

Your example code using the subclassed QVariant: 您使用子类QVariant的示例代码:

#include <QVariant>
#include <QDebug>

class Integer {
    bool null;
    int x;
public:
    Integer() : null(true), x(0) {}
    Integer(int x) : null(false), x(x) {}
    int value() const {
        return x;
    }
    bool isNull() const {
        return null;
    }
};
Q_DECLARE_METATYPE(Integer)

class MyQVariant : public QVariant
{
public:
    MyQVariant(QVariant v) :
      QVariant(v) {}
    bool isNull() const
    {
        if (QString(typeName()) == "Integer")
            return value<Integer>().isNull();
        return QVariant::isNull();   
    }
};

int main(int argc, char *argv[])
{
    Integer x(42);
    Integer y(0);
    Integer z;

    qRegisterMetaType<Integer>("Integer");

    MyQVariant v1(QVariant::fromValue(x));
    MyQVariant v2(QVariant::fromValue(y));
    MyQVariant v3(QVariant::fromValue(z));

    qDebug() << x.isNull() << v1.isNull();
    qDebug() << y.isNull() << v2.isNull();
    qDebug() << z.isNull() << v3.isNull();
}

Output: 输出:

false false 
false false 
true true

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM