-2

I have this TreeItem:

class QJsonTreeItem(object):
def __init__(self, data, parent=None):
    self._parent = parent

    self._key = ""
    self._value = ""
    self._type = None
    self._children = list()
    self.itemData = data

...

def data(self, column):
    if column is 0:
        return self.key
    elif column is 1:
        return self.value

def setData(self, column, value):
    if column is 0:
        self.key = value
    if column is 1:
        self.value = value

...

def insertChildren(self, position, rows, columns):
    if position < 0 or position > len(self._children):
        return False

    for row in range(rows):
        data = [None for v in range(columns)]
        item = QJsonTreeItem(data, self)
        self._children.insert(position, item)

    return True

...

And custom QAbstractItemModel:

class QJsonTreeModel(QAbstractItemModel):

def __init__(self, parent=None):
    super(QJsonTreeModel, self).__init__(parent)

    self._rootItem = QJsonTreeItem(["Key", "Value"])
    self._headers = ("Key", "Value")

...

def data(self, index, role):
    if not index.isValid():
        return None

    if role != Qt.DisplayRole and role != Qt.EditRole:
        return None

    item = index.internalPointer()

    if role == Qt.DisplayRole or role == Qt.EditRole:
        if index.column() == 0:
            return item.data(index.column())

        if index.column() == 1:
            return item.value
    return None

def getItem(self, index):
    if index.isValid():
        item = index.internalPointer()
        if item:
            return item

    return self._rootItem

def setData(self, index, value, role):
    if role == Qt.EditRole:
        item = index.internalPointer()
        item.setData(index.column(), value)
        self.dataChanged.emit(index, index, [Qt.EditRole])
        return True

    return False

def parent(self, index):
    if not index.isValid():
        return QModelIndex()

    childItem = index.internalPointer()
    parentItem = childItem.parent()

    if parentItem == self._rootItem:
        return QModelIndex()

    return self.createIndex(parentItem.row(), 0, parentItem)


...

def insertRows(self, position, rows, parent, *args, **kwargs):
    parentItem = self.getItem(parent)
    
    self.beginInsertRows(parent, position, position + rows - 1)
    success = parentItem.insertChildren(position, rows, self._rootItem.columnCount())
    self.endInsertRows()

    return success

And in my MainWindow file there is a button for adding new items in QTreeView which looks like this:

self.treeView = QTreeView()

self.model = QJsonTreeModel()
self.treeView.setModel(self.model)

...

rightClickMenu = QMenu()            
actionAddItem = rightClickMenu.addAction(self.tr("Add Item"))
actionAddItem.triggered.connect(partial(self.treeAddItem))

...

def treeAddItem(self):
    try:
        index = self.treeView.selectionModel().currentIndex()
        parent = index.parent()

        if self.model.data(parent, Qt.EditRole) == None:
            if not self.model.insertRow(index.row() + 1, parent):
                return

            for column in range(self.model.columnCount(parent)):
                child = self.model.index(index.row() + 1, column, parent)
                self.model.setData(child, "[No data]", Qt.EditRole)
        else:
            pass
    except Exception as exception:
        QMessageBox.about(self, "Exception", "Exception in treeAddItem() function: " + str(exception))  
        return

The question is can I somehow add not an "[No data]" string for QtreeView, but fo example an empty dict() or list()? As far as I understand it only adds an empty strings to the QTreeView, but my task still needs dictionaries and list. If it`s not possible my main idea is to get full tree back to dictionary and to work directly with dictionary items and then load back changed dict to tree, but it seems kinda "bad style".

Can someone help me with this task or offer another idea?

Leonid
  • 34
  • 5
  • You can add any kind of data you want, the important thing is that item views always use roles to *display* the contents. So, you either use another role, to read/write custom types, or you use a delegate that is able to *display* those types. – musicamante Jul 21 '22 at 11:59
  • Please trim your code to make it easier to find your problem. Follow these guidelines to create a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example). – Community Jul 21 '22 at 12:17

1 Answers1

0

The soultion I did is this:

def setData(self, index, value, role=Qt.EditRole):
    if role == Qt.EditRole:
        item = index.internalPointer()
        item.setData(index.column(), value)
        self.dataChanged.emit(index, index, [Qt.EditRole])
        return True
    if role == Qt.DisplayRole:
        item = index.internalPointer()
        item.setData(index.column(), dict())
        self.dataChanged.emit(index, index, [Qt.EditRole])
        return True
    if role == Qt.ToolTipRole:
        item = index.internalPointer()
        item.setData(index.column(), list())
        self.dataChanged.emit(index, index, [Qt.EditRole])
        return True
    return False
Leonid
  • 34
  • 5
  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jul 23 '22 at 05:20