Qt QTextEdit添加虚假行

Qt QTextEdit adds spurious line

本文关键字:添加 QTextEdit Qt      更新时间:2023-10-16

看看这一小段Qt代码

qDebug() << "CONTENT" << content;
QTextEdit *te = new QTextEdit(this);
te->setHtml(content);
qDebug() << "CONTENT AFTER " << te->toHtml();

内容最初包含这个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:'Calibri'; font-size:10pt; font-weight:400; font-style:normal;">
        <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">
            <span style=" font-family:'Verdana'; color:#0b333c;">MY TEXT</span>
        </p>
    </body>
</html>"

…而te->toHtml()的输出为…

<!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">np, li { white-space: pre-wrap; }n</style>
    </head>
    <body style=" font-family:'Calibri'; font-size:10pt; 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;"> </p>
        <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">
            <span style=" font-family:'Verdana'; color:#0b333c;">MY TEXT</span>
        </p>
    </body>
</html>

可以看到,QTextEdit在段落前没有任何理由。这很烦人,我绝对要避免。

任何想法?我实在想不出怎样才能改掉这种习惯。会不会是臭虫?

可能有点晚了,但我已经遇到过几次类似的问题。我发现Qt 使用的HTML解析器不喜欢 HTML缩进,并且将这些空格解释为要格式化的文本,而不是省略它。

要解决这个问题,只需在设置HTML之前删除缩进。

这里有一个完整的测试(代码也可以在这里找到)

#include <qapplication.h>
#include <qtextedit.h>
#include <qdebug.h>
#include <qregexp.h>
int main(int argc, char* argv[])
{
  QApplication a(argc, argv);
  const QString content =
    "<!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:'Calibri'; font-size:10pt; font-weight:400; font-style:normal;">"
    "        <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">"
    "            <span style=" font-family:'Verdana'; color:#0b333c;">MY TEXT</span>"
    "        </p>"
    "    </body>"
    "</html>";
  qDebug() << "Original content";
  qDebug() << content;
  QTextEdit text_edit_1;
  text_edit_1.setHtml(content);
  qDebug() << "";
  qDebug() << "HTML from QTextEdit:";
  qDebug() << text_edit_1.toHtml();
  // Removing spaces (not necessarily the best way, but it works for this example)
  const QString content2 = QString(content).replace(QRegExp("\s+<"), "<");
  qDebug() << "";
  qDebug() << "Content without spaces:";
  qDebug() << content2;
  QTextEdit text_edit_2;
  text_edit_2.setHtml(content2);
  qDebug() << "";
  qDebug() << "HTML from QTextEdit:";
  qDebug() << text_edit_2.toHtml();
  QTextEdit text_edit_3;
  text_edit_3.setHtml(text_edit_2.toHtml());
  qDebug() << "";
  qDebug() << "After re-using HTML:";
  qDebug() << text_edit_3.toHtml();
  return 0;
}

我使用Qt 5.1.0进行了测试,结果如下(我只对输出HTML进行了漂亮的格式化,以简化检查):

原内容结果

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">n<html>
  <head>
    <meta name="qrichtext" content="1" />
    <style type="text/css">np, li { white-space: pre-wrap; }n</style>
  </head>
  <body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;">n<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">        </p>n<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">
      <span style=" font-family:'Calibri'; font-size:10pt;">        </span>
    </p>n<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">
      <span style=" font-family:'Calibri'; font-size:10pt;">            </span>
      <span style=" font-family:'Verdana'; font-size:10pt; color:#0b333c;">MY TEXT</span>
      <span style=" font-family:'Calibri'; font-size:10pt;">            </span>
    </p>
  </body>
</html>

从内容中删除标签之间的缩进和空格后的结果

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">n<html>
  <head>
    <meta name="qrichtext" content="1" />
    <style type="text/css">np, li { white-space: pre-wrap; }n</style>
  </head>
  <body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;">n<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">
      <span style=" font-family:'Verdana'; font-size:10pt; color:#0b333c;">MY TEXT</span>
    </p>
  </body>
</html>

QTextEdit::toHtml()生成的HTML结果

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">n<html>
  <head>
    <meta name="qrichtext" content="1" />
    <style type="text/css">np, li { white-space: pre-wrap; }n</style>
  </head>
  <body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;">n<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">
      <span style=" font-family:'Verdana'; font-size:10pt; color:#0b333c;">MY TEXT</span>
    </p>
  </body>
</html>

也可以看到,QTextEdit生成的HTML可以重新插入到文档中,而不需要添加虚假的行。

值得注意的是,所有这些也适用于QTextDocument,它基本上是QTextEdit使用的底层结构。