QTableView 的 HTML 渲染器 - 字体大小发生了啥变化?

Posted

技术标签:

【中文标题】QTableView 的 HTML 渲染器 - 字体大小发生了啥变化?【英文标题】:HTML renderer for QTableView - what's happening to the font size?QTableView 的 HTML 渲染器 - 字体大小发生了什么变化? 【发布时间】:2021-02-08 19:24:22 【问题描述】:

This answer(由我从那里的其他答案更新)到关于如何在QTableView 中呈现 html 的问题肯定会产生标记的文本外观。

但是字体大小有问题。请参阅此 MCE:第 0 列使用标准 paintsizeHint 方法。您可以单击右侧的单元格以查看 print 语句说这是 12 号字体。但它不是那样显示的。

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())

【问题讨论】:

【参考方案1】:

如果您不使用 options.font,检查它是没有意义的:您更改了小部件上的字体,但 QTextDocument 无法知道任何信息

只需使用选项设置正确的字体:

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

拜托,永远不要修改 pyuic 文件,除非您真的知道自己在做什么以及为什么,这被认为是不好的做法,并且提供这样做的代码不是好东西。

【讨论】:

谢谢!我也会更新引用的答案。实际上,在发布此 MCE 后,我记得有一纳秒的时间,当您看到任何改编的 pyuic 代码的痕迹时,您会很生气!至于paintsizeHint 中的所有这些代码,正如我在参考答案中所说,我不知道这里发生了什么:我对 PyQt5 中的画家等一无所知。 @mikerodent 我的意见没有影响:它不好的做法。这样做绝对有没有的好处(甚至没有为帖子创建小示例 - 花点时间让你的示例正确,它会提高你的问题的质量,甚至让你投票而不是downvotes),而继续这样做有很多的缺点。关于绘画,我建议您研究有关您正在使用的所有功能的文档,当“改编”他人编写的代码时,了解该代码的作用非常重要。不要只是复制/粘贴/编辑,要从中学习 “从中学习”。哈哈,当然:找时间。如果引用问题中的答案包括您的setDefaultFont 行,我就不必打扰您了。至于否决票,与其他地方相比,我发现 SO (pyqt5) 的这个角落由一些非常管教的保管人监管,所以我已经习惯了。

以上是关于QTableView 的 HTML 渲染器 - 字体大小发生了啥变化?的主要内容,如果未能解决你的问题,请参考以下文章

QTableView / QTableWidget:使用 Qt 设计器拉伸最后一列

浏览器中的页面

问我Chrome浏览器的渲染原理(6000字长文)

将按钮添加到 QTableview

如何在 Qt 的 QTableView 中显示一个简单的 QMap?

用于可滚动窗格的纯 Java HTML 查看器/渲染器 [关闭]