QTreeWidget选择第一项

问题描述 投票:4回答:1

我正在从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)

我实际上有两个问题:

  1. 主要问题:在这种情况下,有没有办法选择树中的第一个项目foo。我试着用setCurrentItem()setCurrentIndex()做些什么,但是无法让它发挥作用。我已经搜索了一下,但我找到的所有解决方案都适用于模型。
  2. (可选)这个递归函数是一个很好的方法吗,还是有更好的方法?
python qt pyqt pyside
1个回答
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()
© www.soinside.com 2019 - 2024. All rights reserved.