pythonpyqt5qtreeviewqstyleditemdelegate

Applying QStyledItemDelegate to a cell in QTreeView


I'm developping an application that allows to read and edit json files on pyqt5; the aplication lets the user make changes to the data, by default it lets the user edit by hand the fields, however I prefer them to select the information from the a set of options to avoid wrong editions.

To achieve this I am creating an multiple delegates, as an exaple in the code below Delegate_1 and delgate_2 that inherit from QStyledItemDelegate and rewrites the createEditor method. Searching in internet I found three methods from the class QTreeView that can be used to apply the delegates to different situations: setItemDelegateForColumn, setItemDelegateForRow and setItemDelegate, the fist two are works for full columns or rows and the third works for the whole tree, however my intention is to use the delegate_1 for cell with the index (0, 1), and the delegate_2 for the index (1, 1).

is there a method of QTreeView or a way to achieve that ?

import sys
from PySide2.QtWidgets import *
from PySide2.QtGui import *
from PySide2.QtCore import *

class Delegate_1(QStyledItemDelegate): 
    def createEditor(self, parent, option, index):
        combo = QComboBox()
        combo.addItem('BINARY')
        combo.addItem('ASCII')
        return combo

    def setModelData(self, editor, model, index):
        txt = editor.currentText()
        model.setData(index, txt)

class Delegate_2(QStyledItemDelegate):
    def createEditor(self, parent, option, index):
        combo = QComboBox()
        combo.addItem('True')
        combo.addItem('False')
        return combo

    def setModelData(self, editor, model, index):
        txt = editor.currentText()
        model.setData(index, txt)

if __name__ == '__main__':

    app = QApplication(sys.argv)

    model = QStandardItemModel(2, 2)
    
    it = QStandardItem('File_mode')
    model.setItem(0, 0, it)
    it = QStandardItem('ASCII') # apply delegate_1 to the cell
    model.setItem(0, 1, it)

    it = QStandardItem('Opened')
    model.setItem(1, 0, it)
    it = QStandardItem('True') # apply delegate_2 to the cell
    model.setItem(1, 1, it)

    t = QTreeView() # <- it's json data 
    t.setModel(model)
    t.setItemDelegateForColumn(1, Delegate_1()) # <- column 1  
    #t.setItemDelegate(Delegate()) # <- all cells
    t.show()
    sys.exit(app.exec_())

Thanks for your help


Solution

  • In the createEditor method, you can call the index.row() and index.column() methods, and depending on the row and column values, create the necessary editor.

    def createEditor(self, parent, option, index):
        if index.row() == 0 and index.column() == 1:
            combo = QComboBox()
            combo.addItem('BINARY')
            combo.addItem('ASCII')
            return combo
        elif index.row() == 1 and index.column() == 1:
            combo = QComboBox()
            combo.addItem('True')
            combo.addItem('False')
            return combo