PyQT and QTreeView: Need to ask for childrens when user clicks on an item
Pergunta
I need to create a QTreeView based on requests.
So, when the user open the application, it should make a request to get the root item for the tree. Once the user clicks on that item, it should ask for the children, and so on.
I couldn't find any working example with requests as I want and I don't even know if this is possible.
Solução
It's quite simple really.
Firstly, connect the tree's expanded signal to a handler, and populate the tree with the root's top-level items.
When the signal is fired, it will pass the index of the expanded item to the handler. The handler can then use this to check whether the item has any children using, say, the model's hasChildren method.
If the item already has children, do nothing; otherwise, populate it with whatever top-level items are appropriate for that item.
UPDATE
Below is a script demonstrates how to build a tree dynamically.
For simplicity, the demo uses a QTreeWidget, thus avoiding the need for a separate model. Additional data is stored within the tree by using QTreeWidgetItem.setData.
Note that the sip
import at the top is only needed for compatibilty between Python 2 and 3 (see here for details). If you're using Python 2, it's not needed.
import sip
sip.setapi('QVariant', 1)
from PyQt4 import QtGui, QtCore
class Window(QtGui.QTreeWidget):
def __init__(self):
QtGui.QTreeWidget.__init__(self)
self.setHeaderHidden(True)
self.itemExpanded.connect(self.handleExpanded)
self.itemClicked.connect(self.handleClicked)
self.handleExpanded(self.invisibleRootItem())
def depth(self, item):
depth = 0
while item is not None:
item = item.parent()
depth += 1
return depth
def requestData(self):
for title in 'One Two Three Four Five'.split():
yield title, 'additional data'
def addItems(self, parent):
depth = self.depth(parent)
for title, data in self.requestData():
item = QtGui.QTreeWidgetItem(parent, [title])
item.setData(0, QtCore.Qt.UserRole, data)
if depth < 3:
item.setChildIndicatorPolicy(
QtGui.QTreeWidgetItem.ShowIndicator)
def handleExpanded(self, item):
if item is not None and not item.childCount():
self.addItems(item)
def handleClicked(self, item, column):
print(item.data(column, QtCore.Qt.UserRole).toPyObject())
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())