I am trying to load child items in a treeview
+top
parent1
parent2
parent3
To start off I populate the model with parent node information only and attach it to a treeview, the tree looks like above.
self.mytreeview=QtGui.Qtreeview()
self.model=QtGui.QStandardItemModel(self.mytreeview)
def initialise_model(self):
'''Populate the model with parent nodes only'''
#open file and process each line, each file line has the parent node info
....
for file_name_entry in fileobject:
parent_item=QtGui.QStandardItem(str(file_name_entry).strip())
parent_item.setData("this is a parent",QtCore.Qt.TooltipRole)
self.model.appendRow(parent_item)
self.mytreeview.setModel(self.model)
At this point none of the parents have any child information. What I want to do next is to update a parent node, when the user clicks on the parent node(just in time or lazy loading of a parents child information).
So when a parent node is clicked, and the signal is emitted
QtCore.QObject.connect(self.ui.treeView, QtCore.SIGNAL('clicked(QModelIndex)'), self.update_model)
update_model code should go fetch the children of that parent, update the model, refresh the tree and expand the parent node.
def update_model(self,index):
'''Update the model by adding children to selected/clicked parent node only'''
parent_node=QtGui.QStandardItem(self.model.itemFromIndex(index))
parent_item_index=index.row()
#open the file called parent_node.txt and get all the child entries from the file...
child_index=0
for child_name_entry in parent_text_fileobject:
child_item=QtGui.QStandardItem(str(child_name_entry).strip())
child_item.setData("this is a child",QtCore.Qt.TooltipRole)
parent_item.setChild(child_index,child_item)
child_index=child_index+1
#Once all the children have been added update the model, by inserting a new row where the parent was
self.model.removeRow(parent_item_index)#remove old parent
self.model.insertRow(parent_item_index,parent_item)#insert new parent with its children
When I try to remove the selected parent node (the one with no children) and try inserting a new parent item (with children) it ends up addding the new parent(with children) above the parent node with no children so I end up with duplicated parent nodes
+top
parent1
parent2
+parent2
child_a
child_b
child_c
parent3
So just to recap, removing and inserting i.e.
#Once all the children have been added update the model, by inserting a new row where the parent was
self.model.removeRow(parent_item_index)#remove old parent
self.model.insertRow(parent_item_index,parent_item)#insert new parent with its children
is a bad idea. Looking at the comments its been suggested that AppendRow() might be the answer, but I am not so certain I believe that
self.model.appendRow(parent_item)#new parent with its children
Would simply add the parent to the bottom of my model and therefore the tree would still have duplicate parent nodes i.e
+top
parent1
**parent2**
parent3
**+parent2**
child_a
child_b
child_c
I think what I am looking for is a way to update an existing node in the model, so that the selected (parent node) can be updated with its children. e.g.
...
self.model.UpdateExisitingNode(node_index)
...
Any suggestions on how to update an node in model? Note I am using Windows and PyQt
Regards
You are duplicating items because you are creating another parent item, you should only create new child items. For example:
from PyQt4 import QtGui
class Widget(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.mytreeview = QtGui.QTreeView(self)
self.setLayout(QtGui.QVBoxLayout())
self.layout().addWidget(self.mytreeview)
self.model = QtGui.QStandardItemModel(self.mytreeview)
self.mytreeview.setModel(self.model)
self.mytreeview.clicked.connect(self.update_model)
self.initialise_model()
def initialise_model(self):
for text in ["parent1", "parent2", "parent3"]:
item = QtGui.QStandardItem(text)
self.model.appendRow(item)
def update_model(self, index):
parent = self.model.itemFromIndex(index)
for text in ["children1", "children2", "children3"]:
children = QtGui.QStandardItem("{}_{}".format(parent.text(), text))
parent.appendRow(children)
self.mytreeview.expand(index)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())