如何从QVariant获取原始的Python数据

15

我最近正在学习Python和Qt。因此,请考虑这会是一个新手问题,但我现在卡住了。

import sys
from PyQt4.QtCore import *

data1 = 'string'
data2 = QVariant(data1)
data3 = data2.toPyObject()

我原本期望data3与data1相同,即为'string'。但是在我的系统中,data3却是

PyQt4.QtCore.QString(u'string')

如果我想要处理的数据像例子那样简单,那么这并不是什么大问题,但我想处理'dict'类型的数据,所以我需要解决这个问题。

我认为这是编码问题,但找不到如何解决它。

*在每个文档中,我都声明了以下内容:

#-*- coding: utf-8 -*-

2
你可以通过QString API设置为2来解决这个“问题”,但是,你为什么需要转换为QVariant再转回去呢? - Avaris
3个回答

15

你可以通过将数据封装在不可变容器中来解决此问题:

>>> from PyQt4.QtCore import QVariant
>>> data = {'key1': 123, 'key2': 456}
>>> v = QVariant((data,))
>>> v.toPyObject()[0]
{'key2': 456, 'key1': 123}

如何(使用data,)使数据不可变?只是使用(data),它是否表现为不可变,还是添加“,”使其成为元组? - Ciasto piekarz
3
@san。这并不使数据不可变。如果将数据放入不可变的容器(例如元组)中,则不会尝试进行转换。元组无法转换为等效的C++类型,因此元组及其内容都将保持不变。另外值得指出的是,这种方式还具有性能优势,因为它绕过了Python和C++类型之间来回转换的所有开销。 - ekhumoro

0

在比较 data1data3 之前,您需要将 QString 转换为 Python 字符串,只需编写:

>>> same_as_data1 = str(data3)

现在你已经得到了相同的字符串:

>>> data1 == data
data1 == same_as_data1
True

无论字符串出现在哪里(作为键或值),它都将被映射到QString。您可以手动进行转换,例如:
d = QVariant({'key1':123}).toPyObject()
d_with_str_keys = dict((str(k), v) for k,v in d.iteritems())

或者你可以像Avaris上面指出的那样改变QString的行为。


感谢您的回答。是的,它适用于字符串。你能告诉我如何处理“dict”类型的数据吗?code QVariant({'key1':123}).toPyObject() codecode{PyQt4.QtCore.QString(u'key1'): 1234}code ,我无法将其转换为原始字典类型的数据。 - Jonas Hong

-2
你可以将字典转换为字符串,然后再使用 eval(str) 将其转换回字典:
pydict  = {'key1': 'val1', 'key2': 'val2'}
variant = QtCore.QVariant( pydict )
...
pydict = eval( str( variant.toString() ) )
print pydict
>>> {'key1': 'val1', 'key2': 'val2'}

请记住,如果无法将键或值之一从字符串转换为字典,则eval可能会失败。如果您拥有非内置类型(如str,int,list..),则可能会发生这种情况,但在您的情况下,它将没有问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接