1

Question:

Why does the Python-equivalent of this answer

class CustomDelegate(QtGui.QStyledItemDelegate):
    def paint(self, painter, option, index):
        opt = QtGui.QStyleOptionViewItem(option)
        self.initStyleOption(opt, index)
        opt.text = "Test Text"
        QtGui.QApplication.style().drawControl(QtGui.QStyle.CE_ItemViewItem, opt, painter)

not draw anything into my listview, while I can draw various other widgets with arbitrary labeling by passing the right QStyleOption including necessary members and the text-member set to the desired text like so:

class CustomDelegate(QtGui.QStyledItemDelegate):
    def paint(self, painter, option, index):
        opt = QtGui.QStyleOptionButton()
        opt.rect = option.rect
        opt.text = "Test Text"
        QtGui.QApplication.style().drawControl(QtGui.QStyle.CE_PushButton, opt, painter)

Problem Background:

In PySide I have a QFileSystemModel applied to a QListView and want to display the file names without the file extensions.
My plan was to apply a CustomDelegate which inherits QStyledItemDelegate and to alter the text member of a QStyleOptionViewItem inside the paint()-function just as you can see in my first code sample above. Only difference: "Test Text" is replaced by os.path.splitext(index.data())[0].

Although the items get inserted into the listview, (I can tell by the appearing scroll bar and by clicking anywhere in the list and printing the active item) the items are not painted at all and stay invisible.

The same happens if I don't try to alter anything and pass the original option-parameter:

class CustomDelegate(QtGui.QStyledItemDelegate):
    def paint(self, painter, option, index):
        QtGui.QApplication.style().drawControl(QtGui.QStyle.CE_ItemViewItem, option, painter)

Further Info:

If I just call the super-paint()-function, the items are displayed normally:

class CustomDelegate(QtGui.QStyledItemDelegate):
    def paint(self, painter, option, index):
        QtGui.QStyledItemDelegate.paint(self, painter, option, index)

That gave me the idea to pass my own opt to the super-paint():

class CustomDelegate(QtGui.QStyledItemDelegate):
    def paint(self, painter, option, index):
        opt = QtGui.QStyleOptionViewItem(option)
        self.initStyleOption(opt, index)
        opt.text = os.path.splitext(index.data())[0]
        print(opt.text)
        QtGui.QStyledItemDelegate.paint(self, painter, opt, index)

but this displays the file names with extensions as well... although the print() puts the names to the console without extensions.

Strangly, trying to print opt.text before setting it to anything gets me:

AttributeError: 'PySide.QtGui.QStyleOptionViewItem' object has no attribute 'text'

And last: Leaving out the initStyleOption()-call doesn't seem to make any difference in any configuration.

Community
  • 1
  • 1
S818
  • 391
  • 3
  • 15

1 Answers1

1

Finally I found a way to achieve my goal. I still don't know why my CustomDelegate behaves in such a weird and illogical manner, but I realized that I could tackle my problem in an earlier stage and implement a custom QFileSystemModel to assign to my QListView:

class CustomFileSystemModel(QtGui.QFileSystemModel):
    def data(self, index, role):
        if role == QtCore.Qt.DisplayRole:
            return os.path.splitext(QtGui.QFileSystemModel.data(self, index, role))[0]
        else:
            return QtGui.QFileSystemModel.data(self, index, role)

That way I can just drop my CustomDelegate and the standard QStyledItemDelegate assigned to the QListView per default gets the already shortened file names passed. I think that is an even more elegant way, but it is still unsatisfying to not know about what's going on with this CustomDelegate. So if someone ever finds a real answer to all that, I would really appreciate her/him sharing it!

S818
  • 391
  • 3
  • 15