Sunday, April 3, 2011

Convert a QVariant of a custom type to a QString.

I have a custom class called Money that I have declared with Q_DECLARE_METATYPE().

class Money {
public:
  Money(double d) {
    _value = d;
  }
  ~Money() {}
  QString toString() const {
    return QString(_value);
  }
private:
  double _value;
};
Q_DECLARE_METATYPE(Money);

Money m(23.32);

I store that in a QVariant and I want to convert it to a QString:

QVariant v = QVariant::fromValue(m);

QString s = v.toString();

Variable s ends up being a null string because QVariant doesn't know how to convert my custom type to the string. Is there any way to do this?

From stackoverflow
  • What happens if you try it this way?

    class Money {
    public:
      Money(double d) {
        _value = d;
      }
      ~Money() {}
      QString toString() const {
        return _value.toString();
      }
    private:
      double _value;
    };
    
    dirkgently : You sure you can call a method on a native datatype?
    darkadept : Nope. double does not have a .toString() method. That wouldn't work.
  • Are you sure the following works?

    return QString(_value);

    I don't seem to find a QString ctor that takes a double. You will have to do the conversion here yourself. The Qt way is to:

    QString toString() const {
     QVariant d(_value);
     return d.ToQString();
    }
    
    darkadept : You're right, there is no ctor that takes a double. I should have written that line as "return QString::number(_value);"
    dirkgently : Either should fix your problem.
  • Ok I found one way to do this. I created a parent type called CustomType with a virtual method that I can implement to convert my custom type to a "normal" QVariant:

    class CustomType {
    public:
      virtual ~CustomType() {}
      virtual QVariant toVariant() const { return QVariant(); }
    };
    

    I then inherited my custom Money class from this.

    class Money : public CustomType {
    public:
      Money(double d) {
        _value = d;
      }
      ~Money() {}
      QVariant toVariant() {
        return QVariant(_value);
      }
    private:
      double _value;
    };
    

    This allows me to pass my custom Money variables contained in QVariants so I can use them in the Qt property system, model/view framework, or the sql module.

    But if i need to store my custom Money variable in the database (using QSqlQuery.addBindValue) it can't be a custom class, it has to be a known type (like double).

    QVariant myMoneyVariant = myqobject.property("myMoneyProperty");
    void *myData = myMoneyVariant.data();
    CustomType *custType = static_cast<CustomType*>(myData);
    QVariant myNewVariant = ct->toVariant();
    

    myNewVariant now has the type of double, not Money so I can use it in a database:

    myqsqlquery.addBindValue(myNewVariant);
    

    or convert it to a string:

    QString s = myNewVariant.toString();
    
    darkadept : I think the void *QVariant::data() method isn't in the Qt documentation.

0 comments:

Post a Comment