<p>在<a href="https://stackoverflow.com/a/20430792/984421">one of my other answers</a>中,对于一个类似的问题,我编写了一个简单的演示,它序列化为xml。在</p>
<p>同样的代码可以很容易地适应QDataStream。我并不是真的推荐这个解决方案(可能有几十种不同的方法来实现同一个目标),但它至少提供了一个有效的例子:</p>
<pre><code>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_())
</code></pre>