我正在从XML文件中创建QTreeWidget
。 XML如下所示,我想创建一个名称树:
<root>
<f name='foo'>bar
<f name='foo2'>baz</f>
</f>
</root>
目前我正在使用以下代码(有点简化的代码):
import lxml.etree as et
#...
self.xml = et.XML(filters.filtersxml)
self.tree_widget = QTreeWidget(parent)
def add_items(parent, xmlroot):
for i in xmlroot.getchildren():
item = QTreeWidgetItem(parent, [i.get('name')])
if len(i.getchildren()) != 0:
add_items(item, i)
add_items(self.tree_widget, self.xml)
我实际上有两个问题:
setCurrentItem()
和setCurrentIndex()
执行某些操作,但无法使其正常工作。我已经搜索了一下,但我发现的所有解决方案都适用于模型。答案 0 :(得分:9)
递归是好的,会保持这种方式,并回答你的主要问题:
# after all your code
add_items(self.tree_widget, self.xml)
# select the root item
self.tree_widget.setCurrentItem(self.tree_widget.topLevelItem(0))
当你调用setCurrentItem时,你必须确保该项已经被添加到树中 - 否则它将无法正常工作。有些方法要求项目已经与树相关联(如setExpanded和setSelected)
修改强>
要在不影响树的情况下递归建立,您可以执行以下操作:
import lxml.etree as et
#...
self.xml = et.XML(filters.filtersxml)
self.tree_widget = QTreeWidget(parent)
def add_items(parent, xmlroot):
output = []
for i in xmlroot.getchildren():
item = QTreeWidgetItem(parent, [i.get('name')])
output.append(item)
if len(i.getchildren()) != 0:
add_items(item, i)
return output
items = add_items(None, self.xml)
self.tree_widget.addTopLevelItems(items)
self.tree_widget.setCurrentItem(items[0])
编辑2:一次加载所有
为了进一步了解兔子洞,我个人这样做的方式尽可能地减少不必要的电话和列表将是孩子们只建立一次循环:
import lxml.etree as et
#...
self.xml = et.XML(filters.filtersxml)
self.tree_widget = QTreeWidget(parent)
def create_item(parent, xmlroot):
item = QTreeWidgetItem(parent, [xmlroot.get('name')])
for xmlchild in xmlroot.getchildren():
create_item(item, xmlchild)
return item
items = [create_item(None, xmlchild) for xmlchild in self.xml.getchildren()]
self.tree_widget.addTopLevelItems(items)
if ( items ):
self.tree_widget.setCurrentItem(items[0])
编辑3:动态加载
因为它被提出了......一种动态加载孩子的方法是存储每个级别并在扩展后加载它们:
import lxml.etree as et
from PyQt4.QtGui import QTreeWidgetItem
# ...
class XmlTreeWidgetItem(QTreeWidgetItem):
def __init__( self, parent, xmlitem ):
super(MyTreeWidgetItem, self).__init__(parent)
self.setText(0, xmlitem.get('name'))
self.setChildIndicatorPolicy(self.ShowIndicator)
self._xmlitem = xmlitem
self._loaded = False
def loadChildren( self ):
if ( self._loaded ):
return
self._loaded = True
self.setChildIndicatorPolicy(self.DontShowIndicatorWhenChildless)
for xmlchild in self._xmlitem.getchildren():
XmlTreeWidgetItem(self, xmlchild)
# ...
class SomeClass(QWidget):
def __init__( self, parent = None ):
super(SomeClass, self).__init__(parent)
self.tree_widget = QTreeWidget(parent)
xml = et.XML(filters.filtersxml)
items = [XmlTreeWidgetItem(None, xchild) for xchild in xml.getchildren()]
self.tree_widget.addTopLevelItems(items)
if ( items ):
self.tree_widget.setCurrentItem(items[0])
# create connections
self.tree_widget.itemExpanded.connect(self.loadItem)
def loadItem( self, item ):
item.loadChildren()