[PyQt] PyQt Custom user types with QVariants and QMetaTypes

Phil Thompson phil at riverbankcomputing.com
Tue Jun 21 11:03:37 BST 2011


On Mon, 20 Jun 2011 13:44:47 -0700, Justin Rosen <jmylesrosen at gmail.com>
wrote:
> Hey all,
> 
> I've been struggling the past few days with trying to wrap my mind
around
> how PyQt has implemented QVariants and QMetaTypes.  In short I'm trying
to
> register/declare a custom user type that will be picked up by
> QItemEditorFactory.
> 
> I've found a few postings related to the topic, but have been unable to
get
> a working example.  I'm using Qt 4.6.1 and PyQt 4.7.2 on Linux Red Hat
> Enterprise 5.5
> 
> The FAQ clearly states that this is doable: "Can I store a python object
> reference in a
> QVariant?"<http://article.gmane.org/gmane.comp.python.pyqt-pykde/11833>
> And the original thread covering the issue in the FAQ: Construct
QVariant
> from object of user
>
type<http://old.nabble.com/Construct-QVariant-from-object-of-user-type-td16677823.html>
> .
> 
> I'm able to store a python object on a QVariant and get the object back,
> For
> example the following class Triplet:
>>>> class Triplet:
> ...    def __init__(self):
> ...        self.first, self.second, self.third = (-1, -1, -1)
> 
>>>> t = Triplet()
>>>> tv = QtCore.QVariant(t)
>>>> assert tv.toPyObject() is t
> True
> 
> But I can't seem to derive the type/userType as being a Triplet.  Comes
> back
> as PyQt_PyObject and UserType:
>>>> tv.type()
> 127
>>>> tv.typeName()
> 'PyQt_PyObject'
>>>> tv.typeToName(tv.type())
> 'UserType'
>>>> tv.userType()
> 260
>>>> tv.typeToName(tv.userType())
> 'PyQt_PyObject'
> 
> What am I doing wrong?  The FAQ says that new python types are
> automatically
> registered, but I keep getting the same PyObject type.
> "The QVariant() ctor will now register new Python types automatically.
I've
> also wrapped QMetaType.type() and overloaded it so that you can pass a
> Python type. I think this is enough for what you need."
> 
> In a previous post Matt Newell posted some code that achieves this, but
I'm
> assuming this has been superseded by integration with sip?:
>>>> class A: pass
>>>> metaTypeId = registerPythonQMetaType(A)
>>>> print metaTypeId
> 424
>>>> qv = qvariantFromPyObject(A())
>>>> qv
> <PyQt4.QtCore.QVariant object at 0xb7d2ec2c>
>>>> qv.userType()
> 424
>>>> print qv.typeName()
> A
>>>> pyObjectFromQVariant(qv)
> <__main__.A instance at 0xb65391ec>
> 
> Thanks, any help would be greatly appreciated!
> Justin

You aren't doing anything wrong (except looking at old information).
Python types are not individually registered. The only way to get the type
is to get the object and introspect it.

Phil


More information about the PyQt mailing list