Search code examples
pythonpyqtpyqt4qtreewidgetqtreewidgetitem

How to make QTreeWIdgetItems editable selectively


enter image description here

All the cells are currently editable (editable on double-click). I only need the column 0 to be editable and all others not. How to achieve this?

from PyQt4 import QtCore, QtGui
app = QtGui.QApplication([])

class Tree(QtGui.QTreeWidget):
    def __init__(self, *args, **kwargs):
        super(Tree, self).__init__()
        for i, item_name in enumerate(['Item_1','Item_2','Item_3','Item_4','Item_5']):
            rootItem = QtGui.QTreeWidgetItem()
            rootItem.setFlags(rootItem.flags() | QtCore.Qt.ItemIsEditable)
            for n in range(7):
                rootItem.setText(n, 'Root %s row %s'%(i, n)  )

            rootItem.sceneSG={}
            rootItem.sceneSG['code']='nextSceneFilename'

            for number in range(5):
                childItem = QtGui.QTreeWidgetItem(rootItem)
                childItem.setFlags(rootItem.flags() | QtCore.Qt.ItemIsEditable)
                childItem.sceneSG={}     
                for m in range(7):
                    childItem.setText(m, 'Child %s row %s'%(number, m)  )

            rootItem.setData(100, 77, QtCore.Qt.UserRole )

            self.addTopLevelItem(rootItem)

        self.setColumnCount(5)
        self.resize(360,240)
        self.show()

tree=Tree()
app.exec_()

Solution

  • Generally, you would do this with the use of a QItemDelegate/QStyledItemDelegate. Delegates give you control over how data from the model is displayed in the view and how data from the controller/view is edited and inserted back into the model. They allow you to do things like custom painting and custom editors. In this case, we just check the column index and refuse to return an editor for anything but the first column.

    class MyDelegate(QtGui.QItemDelegate):
    
        def createEditor(self, parent, option, index):
            if index.column() == 0:
                return super(MyDelegate, self).createEditor(parent, option, index)
            return None
    
    
    delegate = MyDelegate()
    tree.setItemDelegate(delegate)