If you execute this code in python:
from PyQt4 import uic, QtCore, QtGui
qvdict = QtCore.QVariant(dict(name='a'))
print qvdict.toPyObject()
qvtuple = QtCore.QVariant(('name','a'))
print qvtuple.toPyObject())
The result is:
{PyQt4.QtCore.QString(u'name'): PyQt4.QtCore.QString(u'a')}
('name', 'a')
As you can see keys and string values in qvdict are converted to QString but not for the qvtuble.
Is there a way to preserve the dictionary exactly as it was when initialysing the QVariant object when using toPyObject method?
I know I can do the conversion my-self by rebuilding the dictionary and converting each keys and string values, but shouldn't their be a way so Qt give me back the exactly same object?
If anybody knows why Qt is doing this conversion, I'd like understand why it's like this.
PyQt will try to convert to the corresponding C++ type if it can.
For a
dict
, this means aQMap
- but only if all the keys are strings. Otherwise, it just wraps a reference to the originaldict
(i.e. there is no implicit copying).For a
list
, the conversion is to aQList
, but it isn't necessary that all the contained elements are also convertible.For a
tuple
, there is no corresponding C++ type, and so no conversion is attempted (theQVariant
will therefore just contain a wrapped reference).This should immediately suggest a workaround to ensure that any python object is preserved when converting to and from a
QVariant
: simply wrap it in atuple
. However, a better long-term solution might be to avoid the use ofQString
andQVariant
altogether. If you're using Python 2, this can be done using the sip module to switch to the v2 API:Alternatively, you can just use Python 3, where the v2 API is the default.