Eluvatar Eluvatar - 2 months ago 17
C++ Question

How do you determine if a QVariant representing a QObject* is null

I'm using

QMetaObject
to get properties from my object, some of these properties are pointers to classes that inherit from QObject, when using
QMetaProperty::read
I get back a
QVariant
containing the pointer to the value of that property.

Given that
QVariant
I'm unable to determine if the underlying value is null or not.

I've written a unit test to show the issue assuming you already have the
QVariant


TEST(utilsTests, isNull)
{
QObject* object1 = new QObject();
QObject* object2 = nullptr;
EXPECT_NE(nullptr, object1);
EXPECT_TRUE(object2 == nullptr);
QVariant variant1 = QVariant::fromValue(object1);
QVariant variant2 = QVariant::fromValue(object2);
EXPECT_FALSE(Utils::isNull(variant1));//test passes
EXPECT_TRUE(Utils::isNull(variant2));//test fails
}


And here's what I've tried for the implementation of
Utils::isNull


bool Utils::isNull(QVariant value)
{
return value.isNull() ||
value.data() == nullptr ||
value.data() == NULL ||
value.data_ptr().is_null == 1 ||
value == QVariant() ||
value == NULL;
}


Some other things I've tried include:


  1. value.canConvert<QObject*>()
    however this throws a segfault

  2. value.value<QObject*>() == nullptr
    this a also throws a segfault

  3. value.value<void*>() == nullptr
    this always returns true



The reason I'm trying to do this is to convert arbitrary QObjects to json, but that's not important in this scope.

Answer

After some more experimentation I discovered that you can just compare 2 QVariants, if they are both representing a null pointer it will return true, otherwise it will return false. My final implementation of isNull looks like this:

bool Utils::isNull(QVariant value)
{
    //declaring a static variable here, it only get's initlized the first time
    static QVariant nullVariant = QVariant::fromValue((QObject * const)nullptr);
    return value == nullVariant;
}

you might want to call value.isNull() as well so you don't get any false positives.