pythonpyqt5font-sizeqtableviewqstyleditemdelegate

Changing the font size of a QTableView after reimplementing the QStyledItemDelegate paint function in PyQt5


I have implemented a multiline text editor for a QTableView as seen here: Make row of QTableView expand as editor grows in height

One issue I have not yet been able to solve is getting full control over the styling of the painted text. A solution for the font color was provided here: Changing the font color of a QTableView after replacing the default editor with an ItemDelegate QTextEdit in PyQt5

I have set a stylesheet for the QTableView:

self.setStyleSheet(
    """font-size: 14px;
    gridline-color: rgb(60, 60, 60);"""
)

And it works for styling the editor as well as the grid. Ideally, I would like the cells to have the same styling as the rest of the application while having some way of making changes to some of the attributes which would then affect both the editor and the way the cells are painted. Everything I have done so far in order to change the styling of the font has been ignored. I have tried changing the initStyleOption, changing the painter's font, changing the option's font and everything else I could think of.

This is the current paint function:

def paint(self, painter, option, index):
    """
    Method override
    """
    # Remove dotted border on cell focus.  https://stackoverflow.com/a/55252650/3620725
    if option.state & QtWidgets.QStyle.State_HasFocus:
        option.state = option.state ^ QtWidgets.QStyle.State_HasFocus

    self.initStyleOption(option, index)
    painter.save()
    doc = QtGui.QTextDocument()
    doc.setDocumentMargin(3)
    doc.setTextWidth(option.rect.width())
    # changed to setPlainText from setHtml because setHtml was removing all newlines
    doc.setPlainText(option.text)
    option.text = ""
    option.widget.style().drawControl(
        QtWidgets.QStyle.CE_ItemViewItem, option, painter
    )
    painter.translate(option.rect.left(), option.rect.top())

    clip = QtCore.QRectF(0, 0, option.rect.width(), option.rect.height())
    painter.setClipRect(clip)

    layout = doc.documentLayout()
    ctx = layout.PaintContext()
    ctx.palette = option.palette
    layout.draw(painter, ctx)
    painter.restore()

An application wide stylesheet is applied when the program is run:

app = QApplication(sys.argv)
app.setStyleSheet(qtstylish.dark())

I believe the spacing is also different between the editor and the painted cell.

Comparison


Solution

  • When a QTextDocument is created as a standalone object, it can only use the application defaults, including the font.

    Note that using a global stylesheet, even with wildcard selectors does not set the default font for the application, but only for the widgets, and since QTextDocument and QAbstractItemDelegate are not widgets, no style sheet font will be applied.

    While there is no access to stylesheets, the style option argument of the paint() function can provide such information: the argument of the function will be the default style option for the view (viewOptions()), and initStyleOption() will eventually alter the font as long as FontRole returns a valid QFont.

    The solution is then to set the defaultFont() of the document:

    def paint(self, painter, option, index):
        # ...
        doc = QtGui.QTextDocument()
        doc.setDefaultFont(option.font)
        # ...