pythonqtpyqt5qtreewidgetqtreewidgetitem

How to customize Qtreewidget item editor in PyQt5?


I am making a QtreeWidget with item editable,but the problem is with the Item Editor or QAbstractItemDelegate(might be called like this,not sure).I am unable to change the stylesheet,actually i dont know how to do this.And also i want the selected lines(blue in editor) should be according to my wish.like below pictureenter image description here

here i want that blue selected line upto ".jpg",so that anyone cant change that ".jpg". Only ,one can change upto this".jpg"

Here is my code:

import sys
from PyQt5 import QtCore, QtWidgets

class Window(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.button = QtWidgets.QPushButton('Edit')
        self.button.clicked.connect(self.edittreeitem)
        self.tree = QtWidgets.QTreeWidget()
        self.tree.setStyleSheet('background:#333333;color:grey')
        layout = QtWidgets.QVBoxLayout(self)
        layout.addWidget(self.tree)
        layout.addWidget(self.button)
        columns = 'ABCDE'
        self.tree.setColumnCount(len(columns))
        for index in range(50):
            item=QtWidgets.QTreeWidgetItem(
                self.tree, [f'{char}{index:02}.jpg' for char in columns])
            item.setFlags(item.flags()|QtCore.Qt.ItemIsEditable)
    def edittreeitem(self):
        getSelected = self.tree.selectedItems()
        self.tree.editItem(getSelected[0],0)  

if __name__ == '__main__':
    
    app = QtWidgets.QApplication(sys.argv)
    window = Window()
    window.setWindowTitle('Test')
    window.setGeometry(800, 100, 540, 300)
    window.show()
    sys.exit(app.exec_())

Solution

  • You can create your own delegate that only considers the base name without the extension, and then set the data using the existing extension.

    class BaseNameDelegate(QtWidgets.QStyledItemDelegate):
        def setEditorData(self, editor, index):
            editor.setText(QtCore.QFileInfo(index.data()).completeBaseName())
    
        def setModelData(self, editor, model, index):
            name = editor.text()
            if not name:
                return
            suffix = QtCore.QFileInfo(index.data()).suffix()
            model.setData(index, '{}.{}'.format(name, suffix))
    
    
    class Window(QtWidgets.QWidget):
        def __init__(self):
            # ...
            self.tree.setItemDelegate(BaseNameDelegate(self.tree))
    

    The only drawback of this is that the extension is not visible during editing, but that would require an implementation that is a bit more complex than that, as QLineEdit (the default editor for string values of a delegate) doesn't provide such behavior.