我最近花了一些时间研究如何在 PyQt 中使用 QDataStream 和 QTreeWidget。我从来没有找到具体的例子来做这件事,而且 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 保存原生 QTreeWidgets,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21653108/