1

I want to convert a QVariant that stores a string to a value with the template method value(). The same thing can be done with other methods like toInt(), toDouble() and so no.

My problem now is that using for example toDouble(bool *ok = Q_NULLPTR) I can pass as argument a pointer to bool for check if the conversion was gone well. but I can't perform this check with value(). Here a little example to reproduce it.

#include <QVariant>
#include <QDebug>

int main()
{
   QVariant v;
   QString str = "300.0"; //Valid number
   v.setValue(str);

   QVariant v2;
   QString str2 = "3kk.4f"; //Invalid number
   v2.setValue(str2);

   if( v.canConvert<double>() ) {
      qDebug() << "Ok QString to double is permitted";
      qDebug() << "Result: " << v.value<double>();
   }

   if( v2.canConvert<double>() ) {
      qDebug() << "Yes QString to double is already permitted";
      qDebug() << "Result: " << v2.value<double>();
      //Oh oh result is 0.0 but is string invalid or it really contain value 0 ?
   }

   return 0;
}

Some tips on how to do this conversion check using the template method value()?

Yoon5oo
  • 496
  • 5
  • 11
Elia
  • 1,417
  • 1
  • 18
  • 28
  • Can't you call `convert()` before `value()` and check `convert()`'s return value? – peppe Jun 24 '17 at 20:38
  • `convert()` require a `int targetTypeId` that in current version of Qt (5.9) is marked as obsolete and Its use is discouraged [here](http://doc.qt.io/qt-5/qvariant-obsolete.html). Moreover there is no template way to keep this `targetTypeId` and in my application the type comes from a template. – Elia Jun 24 '17 at 21:35
  • 1
    Uh, no, don't use *that* enumeration. Use `qMetaTypeId()` instead. See https://doc.qt.io/qt-5/qmetatype.html#qMetaTypeId – peppe Jun 25 '17 at 06:09
  • Thank you @peppe this solution work for me! If you want to write the answer I mark it as the right one! – Elia Jun 25 '17 at 07:15

1 Answers1

4

You can use QVariant::convert(int) passing the metatype id of the target type, which you can obtain via qMetaTypeId<T>(). E.g.

QVariant valid("123.4");
QVariant invalid("123x.y4");

qDebug() << "Types:";
qDebug() << valid.typeName(); // "QString"
qDebug() << invalid.typeName(); // "QString"

// there is a registered QString->double conversion,
// so these will return true
qDebug() << "Can convert:";
qDebug() << valid.canConvert<double>(); // true
qDebug() << invalid.canConvert<double>(); // true

qDebug() << "Convert valid:";
if (!valid.convert(qMetaTypeId<double>()))
    qDebug() << "Conversion failed"; // gets NOT printed

qDebug() << valid.typeName(); // "double"
qDebug() << valid.isNull(); // false
qDebug() << valid.value<double>(); // 123.4

qDebug() << "Convert invalid:";
if (!invalid.convert(qMetaTypeId<double>()))
    qDebug() << "Conversion failed"; // is printed

qDebug() << invalid.typeName(); // "double"
qDebug() << invalid.isNull(); // true
qDebug() << invalid.value<double>(); // 0
peppe
  • 21,934
  • 4
  • 55
  • 70