Got a listview where items need to make use of bold text, so a html delegate is the way to go. I looked around and found several solutions and out of them I made this code, but it has the issue that you can see in the gif, which shows the results with the use of the delegate and without.
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import sys
class HTMLDelegate(QStyledItemDelegate):
def __init__(self, parent=None):
super(HTMLDelegate, self).__init__(parent)
self.doc = QTextDocument(self)
def paint(self, painter, option, index):
painter.save()
options = QStyleOptionViewItemV4(option)
self.initStyleOption(options, index)
self.doc.setHtml(options.text)
options.text = ""
style = QApplication.style() if options.widget is None \
else options.widget.style()
style.drawControl(QStyle.CE_ItemViewItem, options, painter)
ctx = QAbstractTextDocumentLayout.PaintContext()
if option.state & QStyle.State_Selected:
ctx.palette.setColor(QPalette.Text, option.palette.color(
QPalette.Active, QPalette.HighlightedText))
textRect = style.subElementRect(QStyle.SE_ItemViewItemText, options)
painter.translate(textRect.topLeft())
self.doc.documentLayout().draw(painter, ctx)
painter.restore()
if __name__ == '__main__':
app = QApplication(sys.argv)
data = ['1','2','3','4','5','6','7','8','9']
main_list = QListView()
main_list.setItemDelegate(HTMLDelegate())
main_list.setModel(QStringListModel(data))
main_list.show()
sys.exit(app.exec_())
Here are PyQt5 and PySide versions
I dont use sizeHint, since through my testing it didnt feel like it was affecting this behavior. Some attribute is positioning the text wrongly, I have been able to partly counter it with:
self.doc.setDocumentMargin(0)
the default margin is 4, and then move the whole item bit to the right
rect = options.rect
options.rect = QRect(rect.x()+3, rect.y(), rect.width(), rect.height())
But I dont think it addresses the cause of this issue, it just masks it and it becomes a problem again once you try add icons for example