-1

This answer (updated by me from other answers there) to a question about how to render HTML in a QTableView certainly seems to produce a marked-up text look.

But there's a problem with the font size. See this MCE: column 0 uses the standard paint and sizeHint methods. You can click on the right-hand cell to see that the print statement is saying this is a size 12 font. But it's not showing like that.

from PyQt5 import QtWidgets, QtCore, QtGui
import sys

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.resize(1000, 500)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.verticalLayoutWidget = QtWidgets.QWidget(self.centralwidget)
        self.verticalLayoutWidget.setGeometry(QtCore.QRect(20, 20, 800, 300))
        self.verticalLayout = QtWidgets.QVBoxLayout(self.verticalLayoutWidget)
        self.table_view = QtWidgets.QTableView(self.verticalLayoutWidget)
        self.table_view.horizontalHeader().setStretchLastSection(True)
        
        class HTMLDelegate( QtWidgets.QStyledItemDelegate ):
            def __init__( self ):
                super().__init__()
                self.doc = QtGui.QTextDocument()
        
            def paint(self, painter, option, index):
                # default paint op in col 0
                if index.column() == 0:
                    super().paint(painter, option, index)
                    return
                
                options = QtWidgets.QStyleOptionViewItem(option)
                print( f'options {options} font {options.font} size {options.font.pointSize()} F {options.font.pointSizeF()}')
                self.initStyleOption(options, index)
                painter.save()
                self.doc.setTextWidth(options.rect.width())                
                self.doc.setHtml(options.text)
                options.text = ''
                options.widget.style().drawControl(QtWidgets.QStyle.CE_ItemViewItem, options, painter)
                painter.translate(options.rect.left(), options.rect.top())
                clip = QtCore.QRectF(0, 0, options.rect.width(), options.rect.height())
                painter.setClipRect(clip)
                ctx = QtGui.QAbstractTextDocumentLayout.PaintContext()
                ctx.clip = clip
                self.doc.documentLayout().draw(painter, ctx)
                painter.restore()
        
            def sizeHint( self, option, index ):
                # default size hint in col 0
                if index.column() == 0:
                    return super().sizeHint(option, index)
                
                print( f'option {option}' ) 
                options = QtWidgets.QStyleOptionViewItem(option)
                print( f'options {options} font {options.font} size {options.font.pointSize()} F {options.font.pointSizeF()}')
        
                self.initStyleOption(option, index)
                self.doc.setHtml(option.text)
                self.doc.setTextWidth(option.rect.width())
                return QtCore.QSize(self.doc.idealWidth(), self.doc.size().height())
    
        self.table_view.setItemDelegate(HTMLDelegate())
        
        # nice big font
        font = QtGui.QFont()
        font.setPointSize(12)
        self.table_view.setFont(font)
        
        self.table_view.setGeometry(QtCore.QRect(20, 20, 800, 300))
        self.verticalLayout.addWidget(self.table_view)
        self.table_view.setModel(QtGui.QStandardItemModel() )
        self.table_view.model().appendRow([QtGui.QStandardItem('no markup'), 
            QtGui.QStandardItem('here is some <strong>marked up</strong> html <em>text</em>'),])
        MainWindow.setCentralWidget(self.centralwidget)

class MainWindow( QtWidgets.QMainWindow ):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

app = QtWidgets.QApplication(sys.argv)
application = MainWindow()
application.show()
sys.exit(app.exec())
mike rodent
  • 14,126
  • 11
  • 103
  • 157

1 Answers1

1

Checking the options.font is pointless if you don't use it: you altered the font on the widget, but the QTextDocument cannot know anything about that.

Just set the correct font using the option:

    def paint(self, painter, option, index):
        # ...
        self.doc.setDefaultFont(options.font)
        # ...

Please, never modify pyuic files unless you really know what you're doing and why, it's considered bad practice and providing code that does that is not a good thing.

musicamante
  • 41,230
  • 6
  • 33
  • 58
  • Thanks! I'll update the referenced answer too. Actually I remembered a nanosecond after posting this MCE that you get annoyed when you see any traces of adapted pyuic code! As for all this code in `paint` and `sizeHint`, as I say in the referenced answer, I haven't got a clue what is going on here: I know nothing as yet about painters etc. in PyQt5. – mike rodent Feb 08 '21 at 19:38
  • @mikerodent my opinion is ininfluencial: it **is** bad practice. There is absolutely *no* benefit in doing it (not even for creating small examples for a post - take your time and make your example right, it would improve the quality of your question and even get you upvotes instead of downvotes), while there are *lots* of drawbacks in keeping doing it. About painting, I suggest you to study the documentation about all the functions you're using, when "adapting" code written by others it's really important to understand what that code does. Do not just copy/paste/edit, *learn* from it. – musicamante Feb 08 '21 at 19:52
  • "Learn from it". Haha, of course: it's finding the time. If the answers in the referenced question had included your `setDefaultFont` line I would not have had to bother you. As for the down votes, I find this corner of SO (pyqt5) to be policed by some quite officious custodians, compared to elsewhere, so I'm getting used to it. – mike rodent Feb 08 '21 at 20:06