python - PyQt:使用 QDataStream 保存 native QTreeWidgets

标签 python qt python-2.7 pyqt pyqt4

我最近花了一些时间研究如何在 PyQt 中使用带有 QTreeWidget 的 QDataStream。我从来没有找到具体的例子来做到这一点,而且 QDataStream 的 pyqt 文档一般来说似乎非常稀缺。所以我想我会在这里发布一个问题作为面包屑路径,以防其他人需要提示。我会稍等一下,以防有人愿意加入并试一试,我会尽我自己的努力回贴。

问题是:在 PyQt 中,如何使用 QDataStream 将 QTreeWidgetItems 作为 native QT 对象保存到文件中,然后读回文件以完全恢复保存时的树结构?

埃里克

最佳答案

one of my other answers对于类似的问题,我写了一个序列化为 xml 的简单演示。

相同的代码可以很容易地适用于 QDataStream。我并不是真的推荐这个作为解决方案(可能有几十种不同的方法可以实现同样的事情),但它至少提供了一个工作示例:

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

from xml.etree import cElementTree as etree
from PyQt4 import QtGui, QtCore

class Window(QtGui.QWidget):
    def __init__(self, xml):
        QtGui.QWidget.__init__(self)
        self.tree = QtGui.QTreeWidget(self)
        self.tree.header().hide()
        self.button = QtGui.QPushButton('Export', self)
        self.button.clicked[()].connect(self.exportTree)
        layout = QtGui.QVBoxLayout(self)
        layout.addWidget(self.tree)
        layout.addWidget(self.button)
        self._array = QtCore.QByteArray()
        self._buffer = QtCore.QBuffer(self._array, self)
        self._buffer.open(QtCore.QIODevice.ReadWrite)
        self._datastream = QtCore.QDataStream(self._buffer)
        self.importTree(xml)

    def importTree(self, xml):
        def build(item, root):
            for element in root.getchildren():
                child = QtGui.QTreeWidgetItem(item)
                data = element.attrib['data'].encode('ascii')
                self._array.swap(self._array.fromBase64(data))
                self._buffer.reset()
                self._datastream >> child
                build(child, element)
            item.setExpanded(True)
        root = etree.fromstring(xml)
        build(self.tree.invisibleRootItem(), root)

    def exportTree(self):
        def build(item, root):
            for row in range(item.childCount()):
                child = item.child(row)
                self._array.clear()
                self._buffer.reset()
                self._datastream << child
                data = self._array.toBase64().data().decode('ascii')
                element = etree.SubElement(root, 'node', data=data)
                build(child, element)
        root = etree.Element('root')
        build(self.tree.invisibleRootItem(), root)
        from xml.dom import minidom
        print(minidom.parseString(etree.tostring(root)).toprettyxml())

if __name__ == '__main__':

    import sys
    app = QtGui.QApplication(sys.argv)
    window = Window("""\
<?xml version="1.0" ?>
<root>
    <node data="AAAAAQAAAAEAAAAJAAAAQwAB/////wAA
                AAAAAAAAAAEAAAAKAAAAAAYAUgBlAGQ=">
        <node data="AAAAAQAAAAEAAAAJAAAAQwAB//8AAP//
                    //8AAAAAAAEAAAAKAAAAAAgAQwB5AGEAbg==">
            <node data="AAAAAQAAAAEAAAAJAAAAQwAB//8AAICA
                        AAAAAAAAAAEAAAAKAAAAAAoARwByAGUAZQBu"/>
            <node data="AAAAAQAAAAEAAAAJAAAAQwAB//8AAAAA
                        //8AAAAAAAEAAAAKAAAAAAgAQgBsAHUAZQ=="/>
        </node>
        <node data="AAAAAQAAAAEAAAAJAAAAQwAB/////6Wl
                    AAAAAAAAAAEAAAAKAAAAAAwATwByAGEAbgBnAGU=">
            <node data="AAAAAQAAAAEAAAAJAAAAQwAB//+AgAAA
                        gIAAAAAAAAEAAAAKAAAAAAwAUAB1AHIAcABsAGU="/>
            <node data="AAAAAQAAAAEAAAAJAAAAQwAB//8AAICA
                        AAAAAAAAAAEAAAAKAAAAAAoARwByAGUAZQBu"/>
        </node>
    </node>
    <node data="AAAAAQAAAAEAAAAJAAAAQwAB//8AAP//
                //8AAAAAAAEAAAAKAAAAAAgAQwB5AGEAbg==">
        <node data="AAAAAQAAAAEAAAAJAAAAQwAB/////6Wl
                    AAAAAAAAAAEAAAAKAAAAAAwATwByAGEAbgBnAGU=">
            <node data="AAAAAQAAAAEAAAAJAAAAQwAB//8AAP//
                        //8AAAAAAAEAAAAKAAAAAAgAQwB5AGEAbg=="/>
            <node data="AAAAAQAAAAEAAAAJAAAAQwAB//+AgAAA
                        gIAAAAAAAAEAAAAKAAAAAAwAUAB1AHIAcABsAGU="/>
        </node>
        <node data="AAAAAQAAAAEAAAAJAAAAQwAB//8AAICA
                    AAAAAAAAAAEAAAAKAAAAAAoARwByAGUAZQBu">
            <node data="AAAAAQAAAAEAAAAJAAAAQwAB//8AAAAA
                        //8AAAAAAAEAAAAKAAAAAAgAQgBsAHUAZQ=="/>
            <node data="AAAAAQAAAAEAAAAJAAAAQwAB/////wAA
                        AAAAAAAAAAEAAAAKAAAAAAYAUgBlAGQ="/>
        </node>
    </node>
</root>
        """)
    window.setGeometry(800, 300, 300, 300)
    window.show()
    sys.exit(app.exec_())

关于python - PyQt:使用 QDataStream 保存 native QTreeWidgets,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21653108/

相关文章:

c++ - 读取 OpenCV Mat 16bit 到 QImage 8bit Greyscale

python - 如何在 python 3.6.2 中使用 suds.client 库?

Python 2.7 将于 2020 年 1 月 1 日结束其生命周期

python - 在Python循环中添加数字

python - Pandas 外部合并同一 DataFrame 的两个版本

python - 托管在 S3 上的 Flask static_folder

python - 如何在 Pandas 中拆分列标题并正确导出到 Excel

python 将字符串每隔 3 个值拆分一次,但拆分为嵌套格式

c++ - 选中多个项目时如何清除QListView的选择?

multithreading - 有没有一种可移植的方式用 Qt 给线程名称?