11

I will do a method that write data on modbus. I need that QVariant return if is String or Int.

My var.: QVariant dataToWrite

Exist a method that return dataToWrite content is String or Integer? In c# I did how this solution: How do I identify if a string is a number?

I saw documentation on this link: http://doc.qt.io/qt-5/qvariant.html But in qt i didn't find solutions.

Thanks

Mr. Developer
  • 3,295
  • 7
  • 43
  • 110

2 Answers2

15

To know if a QVariant is a QString or an integer you have to use QVariant::type() or QVariant::userType().

bool isInteger(const QVariant &variant)
{
    switch (variant.userType())
    {
        case QMetaType::Int:
        case QMetaType::UInt:
        case QMetaType::LongLong:
        case QMetaType::ULongLong:
            return true;
    }
    return false;
}

bool isString(const QVariant &variant)
{
    return variant.userType() == QMetaType::QString;
}

If you use other methods to get the type of the variant, you will get wrong answers.

For instance:

// This function does not work!
bool isInteger(const QVariant &variant)
{
    bool ok = false;
    variant.toInt(&ok);
    return ok;
}

QString aString = "42";
QVariant var = aString;
isInteger(var); // Returns true, but var.type() returns QMetaType::QString !!!

Now if you want to know if a QVariant can be converted to an integer, you have the beginning of an answer in Qt Documentation:

Returns the variant as an int if the variant has userType() QMetaType::Int, QMetaType::Bool, QMetaType::QByteArray, QMetaType::QChar, QMetaType::Double, QMetaType::LongLong, QMetaType::QString, QMetaType::UInt, or QMetaType::ULongLong; otherwise returns 0.

Which means that there are many non integer variants that can be converted to an integer. The safest way to do it is to use QVariant::canConvert() and QVariant::value():

QString aString = "42";
QVariant var = aString;
if (var.canConvert<int>())
{
    auto anInteger = var.value<int>();
}
Benjamin T
  • 8,120
  • 20
  • 37
  • Not sure if "canConvert" is reliable. I.e. try converting "QVariant(QString, "71.62465753424658")" to an int. "canConvert" will return true, and "value()" will return 0. – Gediminas Jul 06 '20 at 18:54
  • 1
    @Gediminas `canConvert()` only tells you if `QVariant` knows how to convert between 2 types. It does not tell you if the conversion will go well. In your case `QVariant` knows how to convert a `QString` to an `int`: it will call `String::toInt()`, the issue is that `QString::toInt()` will return `0` because `71.62465753424658` is not an `int`. – Benjamin T Jul 06 '20 at 19:07
4

QVariant::canConvert() is a templated method that returns true or false, whether the variant can be converted to a particular type. From its help:

QVariant v = 42;

v.canConvert<int>();              // returns true
v.canConvert<QString>();          // returns true

So it not does check if the construction argument was exactly an int or a string yet looks sufficient for your purposes.

bipll
  • 11,747
  • 1
  • 18
  • 32