[PyQt] Using QVariant.toPyObject to wrap the to* functions

Phil Thompson phil at riverbankcomputing.com
Tue Sep 16 19:49:09 BST 2008


On Wed, 13 Aug 2008 12:37:02 -0700, "Erick Tryzelaar"
<idadesub at users.sourceforge.net> wrote:
> Hello again,
> 
> In our code right now, we keep having to extract data from a QVariant,
> and we end up with a lot of copies of:
> 
> if v.type() == QVariant.Int:
>   ...
> elif v.type() == QVariant.String:
>   ...
> ...
> 
> We don't really care exactly what the type is, but we have to do this
> in order to work directly with the values. Since there's already a
> QVariant.toPyObject that can extract arbitrary python objects, it
> seems like it wouldn't be that much extra work to extend it to be able
> to extract all the QVariant standard types as well. I'd guess that the
> implementation could just be abstracting out the first stage of
> translation, like this:
> 
> QVariant(1).toPyObject() == QVariant(1).toInt()[0]
> QVariant(QDateTime(...)).toPyObject() ==
> QVariant(QDateTime(...)).toDateTime()[0]
> 
> and etc. This makes QVariant a little more pythonic to me, in my opinion.
> 
> I also thought about making the QVariant.List types probably shouldn't
> recursively convert the types, as in:
> 
> # assume v is a c++ QVariant that has QVariantList of QVariant(1),
> QVariant("abc")
> v.toPyObject() == [1, "abc"]
> 
> Since in some cases you might actually want all the contained QVariant
> object returned. You could always do:
> 
> [x.toPyObject() for x in v.toPyObject()]
> 
> Would anyone else find this useful?

This has been implemented in tonight's SIP and PyQt snapshots, although not
quite as described above.

The QVariant ctor will always try and convert the object to a C++ instance
if possible and will leave it as a Python object if it can't do so. For
example, a Python list will be converted to a QList of QVariants, and the
conversion will be applied recursively. This is done because QVariant
cannot know how it is going to be used - it might be being passed to a
wrapped C++ function that wouldn't know what to do with a Python list
object.

QVariant.toPyObject() will return a Python object for all known QVariant
types.

The following should always be true:

QVariant(py_object).toPyObject() == py_object

The following will sometimes be true:

QVariant(py_object).toPyObject() is py_object

The code is now in place to get rid of QVariant completely - which will be
done for PyQt for Python v3.

Phil



More information about the PyQt mailing list