2012-01-12 101 views
1

我想在PyQt中做一个基本的XML故事制造者。到目前为止,我已经能够弄清楚我自己的一切,但我遇到了一些障碍。我无法弄清楚如何将XML文件加载到QTreeWidget中。我需要保留层次结构,但表示层次似乎是随机的。我将发布我的代码,请记住Open函数不起作用(出于显而易见的原因)。 http://pastebin.com/ptHL3M5BPyQt - XML到QTreeWidget

+0

不是真正的答案,但如果你是递归保存,所以也递归加载。 – reclosedev 2012-01-12 16:45:41

回答

3

看起来你可以用QXmlDefaultHandler来做到这一点。

这里有一个简单的演示脚本,显示如何使用它:

from PyQt4 import QtCore, QtGui, QtXml 

class XmlHandler(QtXml.QXmlDefaultHandler): 
    def __init__(self, root): 
     QtXml.QXmlDefaultHandler.__init__(self) 
     self._root = root 
     self._item = None 
     self._text = '' 
     self._error = '' 

    def startElement(self, namespace, name, qname, attributes): 
     if qname == 'folder' or qname == 'item': 
      if self._item is not None: 
       self._item = QtGui.QTreeWidgetItem(self._item) 
      else: 
       self._item = QtGui.QTreeWidgetItem(self._root) 
      self._item.setData(0, QtCore.Qt.UserRole, qname) 
      self._item.setText(0, 'Unknown Title') 
      if qname == 'folder': 
       self._item.setExpanded(True) 
      elif qname == 'item': 
       self._item.setText(1, attributes.value('type')) 
     self._text = '' 
     return True 

    def endElement(self, namespace, name, qname): 
     if qname == 'title': 
      if self._item is not None: 
       self._item.setText(0, self._text) 
     elif qname == 'folder' or qname == 'item': 
      self._item = self._item.parent() 
     return True 

    def characters(self, text): 
     self._text += text 
     return True 

    def fatalError(self, exception): 
     print('Parse Error: line %d, column %d:\n %s' % (
       exception.lineNumber(), 
       exception.columnNumber(), 
       exception.message(), 
      )) 
     return False 

    def errorString(self): 
     return self._error 

class Window(QtGui.QTreeWidget): 
    def __init__(self): 
     QtGui.QTreeWidget.__init__(self) 
     self.header().setResizeMode(QtGui.QHeaderView.Stretch) 
     self.setHeaderLabels(['Title', 'Type']) 
     source = QtXml.QXmlInputSource() 
     source.setData(xml) 
     handler = XmlHandler(self) 
     reader = QtXml.QXmlSimpleReader() 
     reader.setContentHandler(handler) 
     reader.setErrorHandler(handler) 
     reader.parse(source) 

xml = """\ 
<root> 
    <folder> 
     <title>Folder One</title> 
     <item type="1"> 
      <title>Item One</title> 
     </item> 
     <item type="1"> 
      <title>Item Two</title> 
     </item> 
     <item type="2"> 
      <title>Item Three</title> 
     </item> 
     <folder> 
      <title>Folder Two</title> 
      <item type="3"> 
       <title>Item Four</title> 
      </item> 
      <item type="0"> 
       <title>Item Five</title> 
      </item> 
      <item type="1"> 
       <title>Item Six</title> 
      </item> 
     </folder> 
    </folder> 
    <folder> 
     <title>Folder Three</title> 
     <item type="0"> 
      <title>Item Six</title> 
     </item> 
     <item type="2"> 
      <title>Item Seven</title> 
     </item> 
     <item type="2"> 
      <title>Item Eight</title> 
     </item> 
    </folder> 
</root> 
""" 

if __name__ == '__main__': 

    import sys 
    app = QtGui.QApplication(sys.argv) 
    window = Window() 
    window.resize(400, 300) 
    window.show() 
    sys.exit(app.exec_()) 
+0

我将此标记为接受的答案,因为它是您的代码的修改版本,最终为我工作。谢谢! – bojjenclon 2012-05-24 22:54:46

1

您需要自己编写一些东西来从XML文件中提取信息(提示:使用Python的XML解析器,如ElementTree)。此代码将构建一个树小部件,其行(和子箭头)从data填充。

class Tree(QtGui.QTreeWidget): 

    def __init__(self, parent): 
     # maybe init your data here too 
     super(Tree, self).__init__(parent) 

    def populate(self, data): 
     # populate the tree with QTreeWidgetItem items 
     for row in data: 
      # is attached to the root (parent) widget 
      rowItem = QtGui.QTreeWidgetItem(parent) 
      rowItem.setText(0, row) 
      for subRow in row: 
       # is attached to the current row (rowItem) widget 
       subRowItem = QtGui.QTreeWidgetItem(rowItem) 
       subRowItem.setText(0, subRow)