Search code examples
c++c++11qt5stdstringqvariant

conversion between std::string and QVariant (and vice versa) Qt5


I'm having a hard time of converting std::string to QVariant and QVariant back to std::string. In both cases I end up with empty value (default QVariant, just like it was initialized with no parameters) and empty std::string ("").

These are relevant parts of my code:

bool TestItemListModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    // processing of other function arguments, checks, etc.
    (*myData)[row].setName(value.value<std::string>());
    // here I end up with ""
}

QVariant TestItemListModel::data(const QModelIndex &index, int role) const
{
    // again all the checks, etc.
    return QVariant::fromValue<std::string>((*myData)[row].getName());
}

I found a question similar to this one and this is how it was meant to work. I also did additional thing the answer mentioned, so in my main.cpp I have this:

qRegisterMetaType<std::string>("std::string");

and in my testitemlistmodel.h I have this (before class declaration):

Q_DECLARE_METATYPE(std::string)

I use Qt5.8.

EDIT

I found the source for this type of conversion: http://www.qtcentre.org/threads/45922-best-way-to-extend-QVariant-to-support-std-string?p=208049#post208049. Now I just realized it's quite old and may not work anymore. If that's the case, what would be the best way of doing that?


Solution

  • How about using the QString as a median type? It's a little overhead but much easier to maintain the code:

    /* std::string to QVariant */ {
        std::string source { "Hello, World!" };
        QVariant destination;        
    
        destination = QString::fromStdString(source);
        qDebug() << destination;
    }
    
    /* QVariant to std::string */ {
        QVariant source { "Hello, World!" };
        std::string destination;
    
        destination = source.toString().toStdString();
        qDebug() << destination.c_str();
    }
    

    The QVariant has a constructor for QString which can be built from std::string and a QVariant object can be converted to QString which can be coverted to std::string.


    Another option is using QByteArray instead of QString which just copies your std::string character-by-character and doesn't converts it to Unicode like QString does:

    // std::string to QVariant
    myQVariant.setValue<QByteArray>(myStdString.c_str());
    
    // std::string to QVariant
    myStdString = myQVariant.value<QByteArray>().constData();