I am trying to implement a simple model for a treeview and I can't figure out why it isn't working.. It seems that all my nodes are children of my root node although three of them should be children of it's first child. Also I can see that my hasChildren
method gets in an infinite loop.. Any help would be greatly appreciated.
here is my code:
#!/usr/bin/env python2
from PySide import QtGui, QtCore
import sys
class SI(object):
children = []
def __init__(self, group=None, parent=None):
self.parent = parent
self.group = group
def data(self, column):
return self.group[column]
def appendChild(self, group):
self.children.append(SI(group, self))
def child(self, row):
return self.children[row]
def childrenCount(self):
return len(self.children)
def hasChildren(self):
if len(self.children) > 0 :
return True
return False
def row(self):
if self.parent:
return self.parent.children.index(self)
return 0
def columnCount(self):
return len(self.group)
class SM(QtCore.QAbstractItemModel):
root = SI(["First", "Second"])
def __init__(self, parent=None):
super(SM, self).__init__(parent)
self.createData()
def createData(self):
for x in [["a", "A"], ["b","B"], ["c", "C"]]:
self.root.appendChild(x)
for y in [["aa", "AA"], ["ab", "AB"], ["ac","AC"]]:
self.root.child(0).appendChild(y)
def columnCount(self, index=QtCore.QModelIndex()):
if index.isValid():
return index.internalPointer().columnCount()
else:
return self.root.columnCount()
def rowCount(self, index=QtCore.QModelIndex()):
if index.row() > 0:
return 0
if index.isValid():
item = index.internalPointer()
else:
item = self.root
return item.childrenCount()
def index(self, row, column, index=QtCore.QModelIndex()):
if not self.hasIndex(row, column, index):
return QtCore.QModelIndex()
if not index.isValid():
item = self.root
else:
item = index.internalPointer()
child = item.child(row)
if child:
return self.createIndex(row, column, child)
return QtCore.QMOdelIndex()
def parent(self, index):
if not index.isValid():
return QtCore.QModelIndex()
item = index.internalPointer()
if not item:
return QtCore.QModelIndex()
parent = item.parent
if parent == self.root:
return QtCore.QModelIndex()
else:
return self.createIndex(parent.row(), 0, parent)
def hasChildren(self, index):
if not index.isValid():
item = self.root
else:
item = index.internalPointer()
return item.hasChildren()
def data(self, index, role=QtCore.Qt.DisplayRole):
if index.isValid() and role == QtCore.Qt.DisplayRole:
return index.internalPointer().data(index.column())
elif not index.isValid():
return self.root.getData()
def headerData(self, section, orientation, role):
if orientation == QtCore.Qt.Horizontal and role == QtCore.Qt.DisplayRole:
return self.root.data(section)
class MyTree(QtGui.QTreeView):
def __init__(self, parent=None, model=SM):
super(MyTree, self).__init__(parent)
self.setModel(model())
class Window(QtGui.QWidget):
def __init__(self, parent=None):
super(Window, self).__init__(parent)
self.initGui()
def initGui(self):
vlo = QtGui.QVBoxLayout()
tree = MyTree(self)
vlo.addWidget(tree)
self.setLayout(vlo)
self.show()
def main():
app = QtGui.QApplication(sys.argv)
win = Window()
exit(app.exec_())
if __name__ == '__main__':
main()
Hmm I think you have almost got it apart from one (strange!) mistake. You declare children
as a class level variable in SI
whereas it should be an instance variable since each SI
can have children. You don't want a single list for all instances.
So I changed the first lines to:
class SI(object):
def __init__(self, group=None, parent=None):
self.parent = parent
self.group = group
self.children = []
def data(self, column):
return self.group[column]
and it all appears to work OK. Of course I haven't tested in detail but that should get you going.
There's a mistake in implementation of:
def rowCount(self, index=QtCore.QModelIndex()):
Instead of:
if index.row() > 0:
there should be:
if index.column() > 0:
Source: http://doc.qt.io/qt-5/qtwidgets-itemviews-simpletreemodel-example.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With