class NestedListTreeView(object): def __init__(self, data, header=None): self.treeView = QTreeView() self.header = header self.model = None self.set_data(data) # Expand the root item. I'm not sure if this is a good idea in # general, but it works well on some examples. Maybe a # heuristic is needed. root_index = self.model.index(0, 0, QModelIndex()) self.treeView.setExpanded(root_index, True) # Size all the columns to the size of their current # contents. Note that this ignores contents for values in the # tree that are collapsed by default, so it's of limited # use. However, it's better than the default sizing. for i in range(self.model.columnCount(None)): self.treeView.resizeColumnToContents(i) def set_on_clicked(self, callback): def execute(index): callback(index.internalPointer().data) self.treeView.clicked.connect(execute) def set_data(self, data): self.data = data self.model = ListModel(self.data, header=self.header) self.treeView.setModel(self.model) def refresh_data(self): """Refresh the UI's view of all data in the tree view. This may be inefficient with very large data sets. """ root_index = self.model.index(0, 0, QModelIndex()) self.treeView.dataChanged(root_index, root_index)