2015-06-11 7 views
1

Если выполнить этот код в Python:PyQt QVariant со словарем

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.

Есть ли способ сохранить словарь именно так, как это было при инициализации объекта QVariant при использовании метода toPyObject?

Я знаю, что могу сделать преобразование my-self путем перестройки словаря и преобразования всех ключей и строковых значений, но не должен ли это быть таким образом, чтобы Qt вернул мне тот же самый объект?

Если кто-нибудь знает, почему Qt делает это преобразование, я бы хотел понять, почему это так.

ответ

1

PyQt попытается преобразовать в соответствующий тип C++, если это возможно.

Для dict это означает, что QMap - но только если все ключи являются строками. В противном случае он просто переносит ссылку на оригинал dict (т. Е. Неявное копирование).

Для list преобразование относится к QList, но не обязательно, чтобы все содержащиеся элементы были также конвертируемыми.

Для tuple не существует соответствующего типа C++, поэтому никакое преобразование не предпринимается (QVariant будет содержать только обернутую ссылку).

Это должно немедленно предложить обходной путь, чтобы обеспечить сохранение любой объект питон при преобразовании в и из QVariant: просто обернуть его в tuple. Тем не менее, лучшим долгосрочным решением может быть отказ от использования QString и QVariant. Если вы используете Python 2, это можно сделать с помощью sip module к switch to the v2 API:

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

from PyQt4 import QtCore, QtGui 

В качестве альтернативы, вы можете просто использовать Python 3, где v2 API является значением по умолчанию.

+0

Отличное объяснение. Благодаря! –