带字典的 PyQt QVariant

PyQt QVariant with dictionary

如果在python中执行这段代码:

from PyQt4 import uic, QtCore, QtGui
qvdict = QtCore.QVariant(dict(name='a'))
print qvdict.toPyObject()
qvtuple = QtCore.QVariant(('name','a'))
print qvtuple.toPyObject())

结果是:

{PyQt4.QtCore.QString(u'name'): PyQt4.QtCore.QString(u'a')}
('name', 'a')

如您所见,qvdict 中的键和字符串值被转换为 QString,但对于 qvtuble 则没有。

有没有办法在使用 toPyObject 方法时完全保留字典,就像在初始化 QVariant 对象时一样?

我知道我可以通过重建字典并转换每个键和字符串值来自己进行转换,但它们不应该是一种让 Qt 返回完全相同的对象的方法吗?

如果有人知道 Qt 为什么要进行这种转换,我想明白为什么会这样。

如果可以,PyQt 将尝试转换为相应的 C++ 类型。

对于 dict,这意味着 QMap - 但前提是 所有 键都是字符串。否则,它只是包装对原始 dict 的引用(即没有隐式复制)。

对于 list,转换为 QList,但不一定所有包含的元素都可以转换。

对于 tuple,没有相应的 C++ 类型,因此不会尝试转换(因此 QVariant 将只包含一个包装引用)。

这应该立即提出一个解决方法,以确保在与 QVariant 进行转换时保留 any python 对象:只需将其包装在一个tuple。但是,更好的长期解决方案可能是完全避免使用 QStringQVariant。如果您使用 Python 2,可以使用 sip module to switch to the v2 API:

import sip
sip.setapi('QString', 2)
sip.setapi('QVariant', 2)

from PyQt4 import QtCore, QtGui

或者,您可以只使用 Python 3,其中 v2 API 是默认值。