How to customize Qtreewidget item editor in PyQt5?

1k Views Asked by At

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_())
1

There are 1 best solutions below

11
musicamante On BEST ANSWER

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.