使用 Qt 的 QLabel 类更改呈现的 HTML 中的制表位大小
Posted
技术标签:
【中文标题】使用 Qt 的 QLabel 类更改呈现的 HTML 中的制表位大小【英文标题】:Change tab stop size in rendered HTML using Qt's QLabel class 【发布时间】:2009-02-11 19:51:12 【问题描述】:我在 QT QLabel 中呈现一些 html。 HTML 如下所示:
<pre>foo\tbar</pre>
(请注意,我已将“\t”放在代码中有制表符的位置)。
这渲染得很好,但制表符似乎被渲染为 8 个空格,而我希望它被重新渲染为 4。如何更改此 而无需更改源 HTML?
【问题讨论】:
【参考方案1】:根据W3 (HTML4):
水平制表符([ISO10646] 和 [ISO88591] 中的十进制 9)通常被视觉用户代理解释为沿每 8 个字符的制表位排列字符所需的最小非零空格数。 我们强烈反对在预格式化文本中使用水平制表符,因为在编辑时将制表符间距设置为其他值是常见的做法,这会导致文档不对齐。
本质上是实现定义的。大多数(如果不是全部)浏览器/渲染器使用八个空格作为制表符。这不能在 Qt 中配置。
不过,浏览您的 HTML 并将制表符替换为您希望的任意多个空格都有些微不足道。为此编写一个简单的解析器。伪代码:
for each <pre> block
for each line in block
position_in_line = 0
for each character in line
if character is a tab
remove tab character
do
add a space character
++position_in_line
while position_in_line % 8 != 0
else
++position_in_line
如果您好奇,HTML3 指定使用eight-character tabs:
在
中,tab 应该被解释为将水平列位置移动到下一个位置,该位置是同一行上 8 的倍数;即 col := (col+8) mod 8。
【讨论】:
是的,我意识到我可以编辑源代码并将制表符替换为空格字符,但我在问题中明确提到我真的不想开始编辑源 HTML。此外,您的解析器伪代码可以用 python 更容易地编写:code.replace('\t', ' ')【参考方案2】:虽然QLabel
在呈现富文本时在内部使用QTextDocument
,但它不允许在其API 中访问它。不过由于QTextDocument
是QObject
,你可以尝试使用
QTextDocument * tl = label->findChild<QTextDocument>();
访问它(如果 QLabel
创建 QTextDocument
作为其自身的(直接或间接)子级,则将起作用)。
一旦有了指向文本文档的指针,就可以使用QTextDocument
API,例如QTextOption::setTabsStop()
,更改制表位。
最后一步是以某种方式使QLabel
重新绘制自身。可能调用QWidget::update()
就足够了,但缓存(或更糟糕的是,重新创建文本文档)可能会阻止这一点。在这种情况下,您可以在标签上注册一个事件侦听器以在 paintEvent()
之前调整文本文档,但请注意,sizeHint()
也可能在制表位更改时发生更改,因此可能会更复杂。
也就是说,这就是我解决问题的方式。
【讨论】:
遗憾的是,QTextdocument 实例不在 QObject 父子树中(并且通过 d-ptr 技巧访问也是不可能的,因为 QLabel 没有接受 d-ptr 的受保护 ctor),所以似乎最简单的方式可能是退回到 QTextBrowser,或者 smth...【参考方案3】:试试这个:
<pre style="tab-interval:0.5in">foo\tbar</pre>
可以工作
【讨论】:
这不起作用(使用 Qt 5.5.1)。此外,tab-interval
无效。 tab-size
将来可能会派上用场(它也不起作用)。以上是关于使用 Qt 的 QLabel 类更改呈现的 HTML 中的制表位大小的主要内容,如果未能解决你的问题,请参考以下文章
Python Qt GUI设计:QLabel标签类(基础篇—11)