Custom dialogbox (QWidget) as item delegate in QTreeView

205 Views Asked by At

I'm trying to add custom widget (image below) as item delegate in QTreeview. I do see the size of the treeItem getting bigger but my widget does not show up. Not sure what am I missing here. Thanks in advance for all your suggestions.

Custom Widget

item delegate qwidget

Here is the code

ItemNode (node for QAbstractTeeModel)

    class BaseNode:
        def __init__(self, data, parent=None):
            self._data = data
            self._children = list()
            self._parent = None
            if parent:
                parent.addChild(self)

        def addChild(self, node):
            self._children.append(node)
            node._parent = self

        def insertChildren(self, position, children):
            if position < 0:
                return False
            for child in children:
                child._parent = self
                self._children.insert(position, child)
            return True

        def removeChildren(self, position, count):
            if position < 0 or position > len(self._children):
                return False
            for i in range(count):
                child = self._children.pop(position)
                child._parent = None
            return True

        def child(self, row):
            if row < self.rowCount():
                return self._children[row]

        def rowCount(self):
            return len(self._children)

        def columnCount(self):
            return len(self._data)

        def parent(self):
            return self._parent

        def index(self):
            if self._parent:
                return self._parent._children.index(self)
            return 0

        def data(self, column):
            return self._data[column]

QAbstractItemModel

    class NodeModel(QtCore.QAbstractItemModel):
        def __init__(self, parent=None):
            super().__init__(parent)
            self.headers = ["Node"]
            self.root_node = BaseNode(["root"])

        def getNode(self, index):
            if index.isValid():
                node = index.internalPointer()
                if node:
                    return node
            return self.root_node

        def rowCount(self, parent=QtCore.QModelIndex()):
            return self.root_node.rowCount()

        def columnCount(self, parent=QtCore.QModelIndex()):
            return self.root_node.columnCount()

        def data(self, index, role):
            if not index.isValid():
                return
            node = self.getNode(index)
            if role == QtCore.Qt.EditRole or role == QtCore.Qt.EditRole:
                return node

        def headerData(self, section, orientation, role):
            if orientation == QtCore.Qt.Horizontal and role == QtCore.Qt.DisplayRole:
                return self.headers[section]

        def flags(self, index):
            flgs = 0
            if index.isValid():
                flgs = QtCore.Qt.ItemIsEditable
                flgs |= QtCore.Qt.ItemIsEnabled
                flgs |= QtCore.Qt.DisplayRole
            return flgs

        def parent(self, child):
            node = self.getNode(child)
            parent = node.parent()
            if parent == self.root_node:
                return QtCore.QModelIndex()
            return self.createIndex(parent.index(), 0, parent)

        def index(self, row, column, parent):
            parent = self.getNode(parent)
            child = parent.child(row)
            if child:
                return self.createIndex(row, column, child)
            return QtCore.QModelIndex()

        def insertRows(self, row, count, parent=QtCore.QModelIndex(), children=None):
            parent_node = self.getNode(parent)
            self.beginInsertRows(parent, row, row + count - 1)

            result = parent_node.insertChildren(row, children)
            self.endInsertRows()
            return result

        def removeRows(self, row, count, parent=QtCore.QModelIndex()):
            parent_node = self.getNode(parent)
            self.beginRemoveRows(parent, row, row + count - 1)
            success = parent_node.removeChildren(row, count)
            self.endRemoveRows()
            return success

ItemEditor (QWidget for Item Delegate

class ItemEditor(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.ui = Ui_Form()  # this is a UI containing 
        self.ui.setupUi(self)
        self.setAutoFillBackground(True)

Item Delegate

    class NodeDelegate(QStyledItemDelegate):
        def __init__(self, parent=None):
            super().__init__(parent)

        def createEditor(self, parent, option, index):
            if index.column() == 0:
                editor = ItemEditor()
                return editor
            else:
                return super().createEditor(self, parent, option, index)

        def setEditorData(self, editor, index):
            if index.column() == 0:
                pass
            else:
                return super().setEditorData(editor, index)

        def setModelData(self, editor, model, index):
            if index.column() == 0:
                pass
            else:
                super().setModelData(editor, model, index)

        def sizeHint(self, option, index):
            editor = ItemEditor()
            return editor.sizeHint()

        def updateEditorGeometry(self, editor, option, index):
            editor.setGeometry(option.rect)

Implementation in TreeView

    app = QtWidgets.QApplication([])
    tw = QtWidgets.QTreeView()
    model = NodeModel()
    tw.setModel(model)
    for i in "abcd":
        print(i)
        node = BaseNode(data=[i])
        index = model.index(model.root_node.rowCount(), 0, QtCore.QModelIndex())
        model.insertRows(1, 1, index, children=[node])
    
    item_delegate = NodeDelegate()
    tw.setItemDelegateForRow(0, item_delegate)
 
    tw.show()
    app.exec_()
0

There are 0 best solutions below