[Interest] problem converting QVariant UserType to Int
glenn popelka
gpp at popelka.org
Wed Aug 27 01:18:31 CEST 2014
Qt-5.3.1, Fedora 20, g++4.8.3. Also tested on Windows7 with Qt5.2.1 and
5.3.1.
I’m trying to take advantage of the new functionality in Qt5.2 allowing
conversion from a QVariant holding a UserType directly to Integer. I
think this may be a bug, but I could be wrong...
Here's my code, it can all go into main.cpp and built in qtCreator. I
hope it's readable:
#include <QCoreApplication>
#include <QString>
#include <QMetaType>
#include <QDebug>
class UserTypeClass
{
public:
UserTypeClass( int data = 0 );
UserTypeClass( const UserTypeClass& );
int toInt( bool *ok ) const;
private:
int m_data;
};
Q_DECLARE_METATYPE( UserTypeClass );
//---------------------------------------------------------------
UserTypeClass::UserTypeClass( int data ) : m_data( data & 0x03 )
{
qDebug() << "UserTypeClass ctor " << this << ' ' << data << " -> " <<
m_data;
}
//----------------------------------------------------------------
int UserTypeClass::toInt( bool* ok ) const
{
if (ok)
{
*ok = (m_data >= 0 && m_data < 4);
qDebug() << "UserTypeClass::toInt " << this << ' ' << *ok << ' ' << m_data;
}
else
{
qDebug() << "UserTypeClass::toInt " << this << " not set " << m_data;
}
return m_data;
}
//---------------------------------------------------------------
UserTypeClass::UserTypeClass( const UserTypeClass& other ) : m_data(
other.m_data )
{
qDebug() << "UserTypeClass copy " << &other << " to " << this << ' ' <<
m_data;
}
//---------------------------------------------------------------
int main(int argc, char **argv)
{
Q_UNUSED(argc); Q_UNUSED(argv);
int (UserTypeClass::*f)(bool*) const = &UserTypeClass::toInt;
QMetaType::registerConverter< UserTypeClass, int > ( f );
QVariant value;
value.setValue(UserTypeClass(3));
bool b;
int i = value.toInt(&b);
qDebug() << "main(): value = " << i;
}
Output:
=====
UserTypeClass ctor 0x7fff6aa02710 3 -> 3
UserTypeClass copy 0x7fff6aa02710 to 0x194eb20 3 (UserType copied into
QVariant)
UserTypeClass::toInt 0x7fff6aa026f0 false 26537440 (1st conversion
failed, where did 26537440 come from?)
UserTypeClass::toInt 0x194eb20 true 3 (second attempt seems correct, I
expect 3.)
main(): value = 3
=====
The call to value.toInt(&b) in main generates a call to
QVariant::qNumVariantToHelper, which can do 2 attempts to make the
conversion, both of which call back to UserTypeClass::toInt():
from QVariant.cpp:
template <typename T>
inline T qNumVariantToHelper(const QVariant::Private &d,
const HandlersManager &handlerManager, bool *ok, const T& val)
{
...some code omitted...
T ret = 0;
if ((d.type >= QMetaType::User || t >= QMetaType::User)
&& QMetaType::convert(&val, d.type, &ret, t)) {
return ret;
}
if (!handlerManager[d.type]->convert(&d, t, &ret, ok) && ok)
*ok = false;
return ret;
}
The first conversion attempt fails because UserTypeClass::toInt() finds
m_Data > 3. I had to contrive that restriction to demonstrate the
problem. Since I am able to return false, the second conversion is tried
next and it turns out to be the correct one. Note that 'this' from the
copy of UserTypeClass (line 2 of output) is the same as 'this' from the
second attempt at conversion (line 4 of output).
Am I doing this correctly? What is the difference between the two
conversion attempts in QVariant::qNumVariantToHelper?
Thanks,
glenn
More information about the Interest
mailing list