QTreeWidget select first item
pyqt, pyside, python, qt
Solution
Recursive is good, would keep it that way, and in answer to your main question just do:
# after all your code
add_items(self.tree_widget, self.xml)
# select the root item
self.tree_widget.setCurrentItem(self.tree_widget.topLevelItem(0))
You just have to make sure that the item has already been added to the tree when you call setCurrentItem - otherwise it won't really work. Some methods require the item to already be associated to a tree (like setExpanded and setSelected)
Edit
To build up recursively without affecting the tree, you can do:
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])
Edit 2: Loading all at once
And to go a bit further down the rabbit hole, the way that I would personally do this to minimize unnecessary calls and lists as much as possible would be to build the loop the children only once:
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])
Edit 3: Loading dynamically
And since it was brought up...a way to dynamically load the children would be to store each level and load them after being expanded:
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()
Problem
I am making a `QTreeWidget` from a XML file. The XML looks like below and I want to make a tree of the names: ``` <root> <f name='foo'>bar <f name='foo2'>baz</f> </f> </root> ``` At the moment I am using the following code to do so (somewhat simplified code): ``` 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) ``` I actually have two questions about this: - Main question: Is there some way to select the first item in the tree, foo in this case. I tried to do something with `setCurrentItem()` and `setCurrentIndex()`, but couldn't get it to work. I have googled a bit about it, but all the solutions that I found work with models. - (Optional) Is this recursive function a good approach to do this, or is there a better way?