【问题标题】:Assembling a QTextDocument from fragments从片段组装 QTextDocument
【发布时间】:2019-11-23 15:12:47
【问题描述】:

我想将多个QTextDocumentFragments 中的QTextDocument 放在一起,由<HR> 表示的水平规则分隔。像这样的东西(作为 ASCII 模型):

foo
-------
bar
-------
baz

我尝试执行此操作(现在使用insertFragment() 而不是insertFragment(),以尝试使基本方案正常工作,但insertFragment() 也会发生同样的事情)如下所示:

QTextEdit *textedit = ui->descriptionTextEdit;
QTextDocument *textdoc = textedit->document();

textedit->clear();

QTextCursor insertion(textdoc);
insertion.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor);

insertion.insertText("foo");
insertion.insertBlock();
insertion.insertHtml("<HR>");
insertion.insertBlock();
insertion.insertText("bar");
insertion.insertBlock();
insertion.insertHtml("<HR>");
insertion.insertBlock();
insertion.insertText("baz");

qDebug() << textdoc->toHtml();

由此产生的结果确实很奇怪。截图如下:

如您所见,我请求了两个&lt;HR&gt; 标签,但我得到了五个水平规则! QTextDocument 的 HTML 也很奇怪(我添加了几个换行符以使其更具可读性):

<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">
<html>
<head><meta name=\"qrichtext\" content=\"1\" />
<style type=\"text/css\">
p, li { white-space: pre-wrap; }
</style></head>
<body style=\" font-family:'.SF NS Text'; font-size:13pt; font-weight:400; font-style:normal;\">
<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">foo</p>
<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">bar</p>
<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">baz</p>
</body></html>

HTML 中根本没有我的&lt;HR&gt; 标记。使用稍微不同的策略 - 仅在 &lt;HR&gt; 插入之前称为 insertBlock() ,或者仅在它们之后,或者根本不 - 我得到了这个主题的变化;有时 barbaz 在 HTML 输出中不可见,但大量的 &lt;HR&gt; 标签却是。例如,如果我将插入代码更改为:

insertion.insertText("foo");
//insertion.insertBlock();
insertion.insertHtml("<HR>");
insertion.insertBlock();
insertion.insertText("bar");
//insertion.insertBlock();
insertion.insertHtml("<HR>");
insertion.insertBlock();
insertion.insertText("baz");

然后我得到一个结果,在我的应用程序的可见渲染中有四个水平规则,并且有这个 HTML 输出:

<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">
<html><head><meta name=\"qrichtext\" content=\"1\" />
<style type=\"text/css\">
p, li { white-space: pre-wrap; }
</style></head>
<body style=\" font-family:'.SF NS Text'; font-size:13pt; font-weight:400; font-style:normal;\">
<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">foo</p>
<hr />
<hr />
<hr />
<hr />
</body></html>

请注意,barbaz 在 HTML 输出中不可见,尽管它们在应用中呈现可见。

但是,在我发现的代码中,我没有得到我想要的东西。看起来我将QTextDocument 置于某种内部不一致或混乱的状态。那么:这样做的正确方法是什么?

这是 macOS 10.14.6 上的 Qt 5.9.8。

【问题讨论】:

  • 很奇怪...在 Qt 5.12.4 (Win7) 上得到确认。它绝对不喜欢hrs(删除它们似乎使它一切正常)。但是(正在操作的“实时”文档的)“屏幕截图”输出有点红鲱鱼......如果你从一个新的空白QTextDocument开始并执行相同的插入步骤,然后QTextEdit::setHtml(textdoc.toHtml()),它在至少看起来像生成的 HTML 代码。操作 QTextEdit 自己的文档时,它看起来与生成的 HTML 不同(如您的屏幕截图所示)。
  • 大概setHtml(toHtml()) 抹去了不一致的内部状态。但这仍然无法让我到达我想去的地方。

标签: qt qtextdocument qtextcursor


【解决方案1】:

我找到了一个似乎可以接受的解决方法,尽管它不是最佳的。在每个文本片段之间,我现在这样做:

insertion.insertBlock(hrBlockFormat);
insertion.insertText("––––––––––––––––––––");
insertion.insertBlock(defaultBlockFormat);

该字符串是一系列短划线(选项连字符,在 macOS 上)。它们在QTextEdit 中清晰地显示为实线,字符之间没有中断,至少在我碰巧使用的字体中,在 macOS 等上。我不知道这个解决方案的便携性,所以更好解决方案将被接受。但是,水平线的宽度不会填满视图;它仅由您使用的破折号数量决定,这很糟糕。此外,此解决方案当然会在 HTML 中生成一系列破折号,而不是 &lt;HR&gt;;我碰巧不关心这个,但总的来说它也不是最佳的。

块格式设置如下:

QTextBlockFormat defaultBlockFormat;
QTextBlockFormat hrBlockFormat;
hrBlockFormat.setTopMargin(10.0);
hrBlockFormat.setBottomMargin(10.0);
hrBlockFormat.setAlignment(Qt::AlignHCenter);

这使水平规则居中,并在其周围提供一些垂直空间。

【讨论】:

    猜你喜欢
    • 2021-11-09
    • 1970-01-01
    • 1970-01-01
    • 2011-06-10
    • 2011-06-11
    • 2022-08-10
    • 2021-10-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多