首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在python 3.6+和PyQt5中Pickle QPolygon

在python 3.6+和PyQt5中Pickle QPolygon
EN

Stack Overflow用户
提问于 2019-02-28 22:54:53
回答 4查看 785关注 0票数 4

我试图对一个QPolygon进行筛选,然后加载它,但是我得到了一个错误。我已经在Python2和PyQt4上完成了这项工作,但现在我想在Python3和PyQt5上使用它。

我不想读取/加载使用Python2生成的数据!pickle文件只是用来将Qt元素从Python3临时存储到Python3中,比如QPolygons。

我已经为pickle.dump()测试了从1到4的不同协议选项,并尝试使用"fix_imports=True“选项,这在Python3中应该不会有什么不同。

以下是我的简化代码

代码语言:javascript
复制
from PyQt5.QtGui import QPolygon
from PyQt5.QtCore import QPoint
import pickle

file_name = "test_pickle.chip"

with open(file_name, 'wb') as f:
    poly = QPolygon((QPoint(1, 1), QPoint(2, 2))) 
    pickle.dump(poly, f, protocol=2)  # , fix_imports=True)

# loading the data again
with open(file_name, 'rb') as f:
    elem = pickle.load(f, encoding='bytes')  # , fix_imports=True)

我收到以下错误消息,但无法对其执行任何操作:

elem = pickle.load(f,=‘bytes’)#,fix_imports=True) TypeError:索引0的类型为'int‘,但应为'QPoint’

有没有什么可以替代泡菜的?提前感谢!

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2019-02-28 23:37:31

您可以使用QDataStream来序列化/反序列化Qt对象:

代码语言:javascript
复制
from PyQt5 import QtCore
from PyQt5.QtGui import QPolygon
from PyQt5.QtCore import QPoint, QFile, QIODevice, QDataStream, QVariant

file_name = "test.dat"

output_file = QFile(file_name)
output_file.open(QIODevice.WriteOnly)
stream_out = QDataStream(output_file)
output_poly = QPolygon((QPoint(1, 6), QPoint(2, 6)))
output_str = QVariant('foo')  # Use QVariant for QString
stream_out << output_poly << output_str
output_file.close()

input_file = QFile(file_name)
input_file.open(QIODevice.ReadOnly)
stream_in = QDataStream(input_file)
input_poly = QPolygon()
input_str = QVariant()
stream_in >> input_poly >> input_str
input_file.close()

print(str(output_str.value()))
print(str(input_str.value()))
票数 3
EN

Stack Overflow用户

发布于 2019-03-01 00:54:45

通过对文档的一些搜索,可以了解如何通过__reduce__ method实现定制类的定制酸洗。基本上,您返回一个元组,包括要在取消酸选时创建的新对象的构造函数,以及将传递给构造函数的参数元组。然后,您可以选择传递一个state对象(参见__getstate____setstate__)和一些迭代器,以添加位置数据和键值数据。

通过将QPolygon子类化,我们可以像这样添加可拾取性:(这可能是可以清理/重构的,但这是我获得的第一个有效的实现)

代码语言:javascript
复制
from PyQt5.QtGui import QPolygon
from PyQt5.QtCore import QPoint
import pickle

class Picklable_QPolygon(QPolygon):

    def __reduce__(self):
        # constructor, (initargs), state object passed to __setstate__
        return type(self), (), self.__getstate__()

    #I'm not sure where this gets called other than manually in __reduce__
    #  but it seemed like the semantically correct way to do it...
    def __getstate__(self):
        state = [0]
        for point in self:
            state.append(point.x())
            state.append(point.y())
        return state

    #putPoints seems to omit the `nPoints` arg compared to c++ version.
    #  this may be a version dependent thing for PyQt. Definitely test that
    #  what you're getting out is the same as what you put in..
    def __setstate__(self, state):
        self.putPoints(*state)

poly = Picklable_QPolygon((QPoint(1, 1), QPoint(2, 2)))
s = pickle.dumps(poly)

elem = pickle.loads(s)
票数 1
EN

Stack Overflow用户

发布于 2019-03-01 08:50:05

这一定是pyqt5中的错误,因为the documentation states表明支持酸洗QPolygon。因此,请使用您的示例将错误报告发布到pyqt mailing list

同时,到目前为止,最简单的替代方法是使用QSettings

代码语言:javascript
复制
from PyQt5.QtGui import QPolygon
from PyQt5.QtCore import QSettings, QPoint

file_name = "test_pickle.chip"

poly = QPolygon((QPoint(1, 1), QPoint(2, 2)))

# write object
s = QSettings(file_name, QSettings.IniFormat)
s.setValue('poly', poly)

del s, poly

# read object
s = QSettings(file_name, QSettings.IniFormat)
poly = s.value('poly')

print(poly)
print(poly.point(0), poly.point(1))

输出:

代码语言:javascript
复制
<PyQt5.QtGui.QPolygon object at 0x7f871f1f8828>
PyQt5.QtCore.QPoint(1, 1) PyQt5.QtCore.QPoint(2, 2)

这可以用于PyQt支持的任何类型的酸洗,以及PyQt可以convert to/from a QVariant的任何其他类型。PyQt还支持QSettings.value()type参数,该参数可用于显式声明所需的类型。由于QSettings是为存储应用程序配置数据而设计的,因此可以在同一文件中存储任意数量的对象(有点像python的shelve module)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54928431

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档