pythonpyqt5qtreewidgetqtreewidgetitem

QTreeWidgetItem disable editing if tab key is pressed


I have an application which uses a QTreeWidget and QTreeWidgetItems. If a new item gets added to the treeWidget (right click -> add item) it is possible to write in column "Header 1". If the tab key is pressed the focus jumps to the column "Header 0" which can be written as well. The desired behaviour is that by pressing the tab key the QTreeWidgetItem becomes non-editable.

I have alreay tried to solve it by catching the tab key event within a modified QTreeWidgetItem class. Unfortunately the tab key event does not get catched. Example:

from PyQt5 import QtCore, QtGui, QtWidgets

class CTreeWidgetItem(QtWidgets.QTreeWidgetItem):
    def __init__(self, parent=None):
        QtWidgets.QTreeWidgetItem.__init__(self, parent)

    def keyPressEvent(self, event):
        if event.key() == QtCore.Qt.Key_Tab:
            self.setFlags(self.flags() | ~QtCore.Qt.ItemIsEditable)
            print('not working')
    
def create_treeWidget():
    treeWidget = QtWidgets.QTreeWidget()

    treeWidget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
    treeWidget.customContextMenuRequested.connect(openContextMenu)
    
    treeWidget.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
    treeWidget.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
    treeWidget.setTabKeyNavigation(True)
    
    treeWidget.headerItem().setText(0, "Header 0")
    treeWidget.headerItem().setText(1, "Header 1")
    treeWidget.headerItem().setText(2, "Header 2")
        
    return treeWidget

def openContextMenu(event):
    menu = QtWidgets.QMenu()
    action = menu.addAction('add item', addItem)
    menu.exec_(tree.mapToGlobal(event))

def addItem():
    item = CTreeWidgetItem(tree)
    item.setFlags(item.flags() | QtCore.Qt.ItemIsEditable)
    tree.editItem(item, 1)

if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    app.setStyle("fusion")
    tree = create_treeWidget()
    tree.show()
    sys.exit(app.exec_())

Example for problem

  1. Execute script
  2. Right click -> add item
  3. Write something
  4. Press tab key -> focus jumps to different column and text can be edited -> jumping to new column is accepted but item should not be editable.

Solution

  • from PyQt5 import QtCore, QtGui, QtWidgets
    
    class CTreeWidgetItem(QtWidgets.QTreeWidgetItem):
        def __init__(self, parent=None):
            QtWidgets.QTreeWidgetItem.__init__(self, parent)
    
    class CQTreeWidget(QtWidgets.QTreeWidget):
    
        def __init__(self):
            super().__init__()
    
        def edit(self, index, trigger, event):      
            if index.column()==1:
                return super().edit(index, trigger, event)
    
            return False
        
    def create_treeWidget():
        treeWidget=CQTreeWidget()
    
        treeWidget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        treeWidget.customContextMenuRequested.connect(openContextMenu)
        
        treeWidget.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
        treeWidget.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
        treeWidget.setTabKeyNavigation(True)
        
        treeWidget.headerItem().setText(0, "Header 0")
        treeWidget.headerItem().setText(1, "Header 1")
        treeWidget.headerItem().setText(2, "Header 2")
            
        return treeWidget
    
    def openContextMenu(event):
        menu=QtWidgets.QMenu()
        action=menu.addAction('add item', addItem)
        menu.exec_(tree.mapToGlobal(event))
    
    def addItem():
        item=CTreeWidgetItem(tree)
        item.setFlags(item.flags()|QtCore.Qt.ItemIsEditable)
        tree.editItem(item, 1)
    
    if __name__ == "__main__":
        import sys
    
        app=QtWidgets.QApplication(sys.argv)
        app.setStyle("fusion")
        tree=create_treeWidget()
        tree.show()
        sys.exit(app.exec_())