我最近花了一些时间研究如何在PyQt中将QDataStream与QTreeWidget一起使用.我从未找到具体的示例来执行此操作,而且QDataStream的pyqt文档总体上似乎很稀缺.因此,我想在这里将问题作为面包屑线索发布,以防其他人需要提示.我会稍等一下,以防有人想进来一枪,然后我会尽力而为.
问题是:在PyQt中,如何使用QDataStream将QTreeWidgetItems作为本机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_())