0
votes

By default if a cell is edited in a QTreeWidget, the editor changes its width based on length of text. enter image description here

Is it possible to set the editorĀ“s width to fill the cell?

Here is the code to reproduce the screenshot:

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


class Example(QTreeWidget):

    def __init__(self):
        super().__init__()

        self.resize(600, 400)

        self.setHeaderLabels(['Col1', 'Col2', 'Col3', 'Col4'])
        self.setRootIsDecorated(False)
        self.setAlternatingRowColors(True)
        self.setSelectionBehavior(QAbstractItemView.SelectItems)
        # self.setSelectionMode(QAbstractItemView.SingleSelection)
        self.setStyleSheet('QTreeView { show-decoration-selected: 1;}')

        for i in range(5):
            item = QTreeWidgetItem(['hello', 'bello'])
            item.setFlags(item.flags() | Qt.ItemIsEditable)
            self.addTopLevelItem(item)

def main():

    app = QApplication(sys.argv)
    ex = Example()
    ex.show()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()
1

1 Answers

1
votes

You can create a simple QStyledItemDelegate and override its updateEditorGeometry() in order to always resize it to the index rectangle:

class FullSizedDelegate(QStyledItemDelegate):
    def updateEditorGeometry(self, editor, opt, index):
        editor.setGeometry(opt.rect)


class Example(QTreeWidget):
    def __init__(self):
        # ...
        self.setItemDelegate(FullSizedDelegate(self))

** UPDATE **

The default text editor for all item views is an auto expanding QLineEdit, which tries to expand itself to the maximum available width (the right edge of the viewport) if the text is longer than the visual rectangle of the item. In order to avoid this behavior and always use the item rect, you have to return a standard QLineEdit. In this case the updateGeometry override is usually not necessary anymore (but I'd keep it anyway, as some styles might still prevent that):

class FullSizedDelegate(QStyledItemDelegate):
    def createEditor(self, parent, opt, index):
        if index.data() is None or isinstance(index.data(), str):
            return QLineEdit(parent)
        return super().createEditor(parent, opt, index)