To set widgets on children items on QTreeView
pyqt, qabstractitemmodel, qt4, qtreeview
Solution
Your mistake is on this line:
qindex_widget_child = self._datamodel.index(n, 1, QModelIndex())
self.setIndexWidget(qindex_widget_child, node_widget_child)
It's giving you the index on row 2 column 1 of the model, which is the "2th item", not your child. Your child is on row 1 column 1 of `std_item`. In Qt, especially in QStandardItemModel, Children are stored relative to their parent, not relative to the model.
I'm not familiar enough with PyQt to give you the exact code, but you should be able to do something like this:
qindex_widget_child = std_item_child.index(QModelIndex())
self.setIndexWidget(qindex_widget_child, node_widget_child)
or like this:
qindex_widget_child = std_item.child(0, 1).index(QModelIndex())
self.setIndexWidget(qindex_widget_child, node_widget_child)
Problem
Thanks to this thread, I'm able to add widgets to 2nd or later column of `QAbstractItemView` (in my example QTreeView) of top level items of a `view`. But is it possible to add widgets to the children items? Here's what I've tried which partly went well: ``` #!/usr/bin/env python import os from PyQt4.QtCore import QModelIndex, Qt from PyQt4.QtGui import QApplication, QItemSelectionModel, \ QPushButton, QStandardItem, \ QStandardItemModel, QTreeView from PyQt4.uic import loadUi class PrvTreeviewNest(QTreeView): def __init__(self): super(PrvTreeviewNest, self).__init__() loadUi('/home/user/yourproject/resource/treeview_nest.ui') # row can be 0 even when it's more than 0. self._datamodel = QStandardItemModel(0, 2) self.setModel(self._datamodel) for i in range(4): self._add_widget(i + 1) self.show() def _add_widget(self, n): std_item = QStandardItem('{}th item'.format(n)) self._datamodel.setItem(n, 0, std_item) node_widget = QPushButton('{}th button'.format(n)) qindex_widget = self._datamodel.index(n, 1, QModelIndex()) self.setIndexWidget(qindex_widget, node_widget) if n == 2: std_item_child = QStandardItem('child') std_item.appendRow(std_item_child) node_widget_child = QPushButton('petit button') qindex_widget_child = self._datamodel.index(n, 1, QModelIndex()) self.setIndexWidget(qindex_widget_child, node_widget_child) if __name__ == '__main__': import sys app = QApplication(sys.argv) # window = TreeviewWidgetSelectProve() window = PrvTreeviewNest() # window = TreeviewWidgetSelectProve() window.resize(320, 240) # window.show(); window.setWindowTitle( QApplication.translate("toplevel", "Top-level widget")) # window.add_cols() sys.exit(app.exec_()) ``` treeview_nest.ui is available. You see in the image below that the item `child` doesn't show a button and its parent's button is overwritten. Apparently I have no idea how to write a code for it. Update) I figured out how to add widget to children. Tricky enough, using QStandardItem.insertRow combined with index does the work. In my sample code above, replace `_add_widget` with the following: ``` def _add_widget(self, n): item_toplevel = QStandardItem('{}th item'.format(n)) self._datamodel.setItem(n, 0, item_toplevel) widget_toplevel = QPushButton('{}th button'.format(n)) qindex_toplevel = self._datamodel.index(n, 1, QModelIndex()) self.setIndexWidget(qindex_toplevel, widget_toplevel) if n == 2: item_child_col0 = QStandardItem('child col0') item_child_col1 = QStandardItem('child col1') #item_toplevel.appendRow(item_child_col0) item_toplevel.insertRow(0, [item_child_col0, item_child_col1]) widget_child = QPushButton('child widget') qindex_child = item_child_col1.index() self.setIndexWidget(qindex_child, widget_child) ``` I'm sure this is NOT the best/ideal designed way but seems to work for me. I came up with after inspired by @Phlucious's answer. Thanks!