QTextEdit插入不一致的HTML(当重复/一致地执行相同的操作时)

时间:2016-04-26 02:41:05

标签: c++ qt qt5.6

我正在使用QTextEdit小部件向用户显示格式良好的聊天窗口。为了使其成为测试的基础,我使用以下格式为我的html:

    QString style = is_message_sent_by_myself ?
        "background-color:rgb(255,255,255);font-size:14px;color:rgb(10,10,10);" :
        "background-color:rgb(249,86,79);font-size:14px;color:rgb(255,255,255);";

    QString format("<div style='%1'> %2 </div> <div style='font-size:3px;'> &zwnj; </div>");
    QString text_to_append = format.arg(style).arg(message.toHtmlEscaped());

    QTextEdit->append(text_to_append)

这很好when creating the html myself但是当使用QTextEdit->append(text_to_be_append)使用QT 5.6生成它时,我会得到一个不同的(甚至是不一致的)结果。

首先,在运行上述代码段时,会生成以下html(通过QTextEdit->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">
            p, li { white-space: pre-wrap; }
        </style>
    </head>
    <body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; 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; background-color:#ffffff;"><span style=" font-size:14px; color:#0a0a0a; background-color:#ffffff;">Some message </span></p>
        <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:3px;">&zwnj; </span></p>
    </body>
</html>

which looks perfect代表第一条消息)

但在再次执行代码后,会出现不一致的情况:

<!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:'MS Shell Dlg 2'; font-size:8.25pt; 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; background-color:#ffffff;"><span style=" font-size:14px; color:#0a0a0a; background-color:#ffffff;">Some message </span></p>
        <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:3px;">&zwnj; </span></p>
        <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:14px; color:#ffffff; background-color:#f9564f;">Some message </span></p>
        <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:3px;">&zwnj; </span></p>
    </body>
</html>

looks like this,但should look like this

如您所见,第三个<p>标记中缺少背景颜色属性。背景颜色属性出现在第一个<p>标记中的位置。相反的代码会反复重复,后续调用会生成<p>标记,而不会生成背景颜色属性。

为什么会发生这种情况,我该如何处理这个问题?

我在Windows 10 x64上使用QT 5.6和Visual Studio 2015加载项(非官方加载项)。

这就是我创建QTextEdit框的方式(包括tabPage的所有其他组件):

PAChatClientUI::PAChatClientUI(QTabWidget* tabs_container, QObject *parent)
    : QObject(parent), tabs_container_(tabs_container)
{
    QString suffix = QString::number((size_t)this, 16);

    tab_ = new QWidget();
    tab_->setObjectName("tab_" + suffix);

    tab_grid_layout_ = new QGridLayout(tab_);
    tab_grid_layout_->setSpacing(6);
    tab_grid_layout_->setContentsMargins(11, 11, 11, 11);
    tab_grid_layout_->setObjectName("tab_grid_layout_" + suffix);

    chat_container_grid_ = new QGridLayout();
    chat_container_grid_->setSpacing(6);
    chat_container_grid_->setObjectName("chat_container_grid_" + suffix);

    chat_container_button_grid_ = new QHBoxLayout();
    chat_container_button_grid_->setSpacing(6);
    chat_container_button_grid_->setObjectName("chat_container_button_grid_" + suffix);

    chat_manager_bot_remove_ = new QPushButton(tab_);
    chat_manager_bot_remove_->setObjectName("chat_manager_bot_remove_" + suffix);
    chat_manager_bot_remove_->setMinimumSize(QSize(119, 23));

    chat_container_button_grid_->addWidget(chat_manager_bot_remove_);

    chat_manager_keep_chat_ = new QPushButton(tab_);
    chat_manager_keep_chat_->setObjectName("chat_manager_keep_chat_" + suffix);
    chat_manager_keep_chat_->setMinimumSize(QSize(119, 23));

    chat_container_button_grid_->addWidget(chat_manager_keep_chat_);

    chat_manager_end_chat_ = new QPushButton(tab_);
    chat_manager_end_chat_->setObjectName("chat_manager_end_chat_" + suffix);
    chat_manager_end_chat_->setMinimumSize(QSize(118, 23));

    chat_container_button_grid_->addWidget(chat_manager_end_chat_);

    chat_manager_send_ = new QPushButton(tab_);
    chat_manager_send_->setObjectName("chat_manager_send_" + suffix);
    chat_manager_send_->setMinimumSize(QSize(119, 23));

    chat_container_button_grid_->addWidget(chat_manager_send_);

    chat_container_grid_->addLayout(chat_container_button_grid_, 3, 0, 1, 1);

    chat_box_text_messages_ =
        //new QPlainTextEdit(tab_);
        new QTextEdit(tab_);
    chat_box_text_messages_->setObjectName("chat_box_text_messages_" + suffix);
    chat_box_text_messages_->setMinimumSize(QSize(495, 178));

    chat_container_grid_->addWidget(chat_box_text_messages_, 1, 0, 1, 1);

    chat_box_text_input_message_ = new QLineEdit(tab_);
    chat_box_text_input_message_->setObjectName("chat_box_text_input_message_" + suffix);
    chat_box_text_input_message_->setMinimumSize(QSize(495, 20));
    chat_box_text_input_message_->setMaximumSize(QSize(16777215, 16777215));

    chat_container_grid_->addWidget(chat_box_text_input_message_, 2, 0, 1, 1);

    tab_grid_layout_->addLayout(chat_container_grid_, 0, 0, 1, 1);

    chat_manager_bot_remove_->setText("Remove Bot");
    chat_manager_keep_chat_->setText("Keep Chat");
    chat_manager_end_chat_->setText("End Chat");
    chat_manager_send_->setText("Send");

    QPalette p = chat_box_text_messages_->palette();

    p.setColor(QPalette::Active, QPalette::Base, Qt::black);
    p.setColor(QPalette::Inactive, QPalette::Base, Qt::black);
    chat_box_text_messages_->setPalette(p);

    chat_box_text_messages_->setWordWrapMode(QTextOption::WordWrap);
    chat_box_text_messages_->setReadOnly(true);

    //Add nice html messages:
    AddMessage(true, "Some message");

    AddMessage(false, "Some message");

    AddMessage(true, "Some message");

    AddMessage(false, "Some message");

    tabs_container_->addTab(tab_, " 6");
}

void PAChatClientUI::AddMessage(bool me, const QString& message)
{
    QString style = me ?
        "background-color:rgb(255,255,255);font-size:14px;color:rgb(10,10,10);" :
        "background-color:rgb(249,86,79);font-size:14px;color:rgb(255,255,255);";

    QString format("<div style='%1'> %2 </div> <div style='font-size:3px;'> &zwnj; </div>");
    QString safe_msg = format.arg(style).arg(message.toHtmlEscaped());
    qDebug() << "Writing: " << safe_msg;
    chat_box_text_messages_->append(safe_msg);
    qDebug() << "HTML: " << chat_box_text_messages_->toHtml();
}

编辑:

我已经尝试根据答案和我的一个想法编辑代码,为代码产生以下两个结果:

void PAChatClientUI::AddMessage(bool me, const QString& message)
{
    QString style = me ?
        "background-color:rgb(255,255,255);font-size:14px;color:rgb(10,10,10);" :
        "background-color:rgb(249,86,79);font-size:14px;color:rgb(255,255,255);";

    QString format("<div style='%1'> %2 </div> <div style='font-size:3px;'> &zwnj; </div>");
    QString safe_msg = format.arg(style).arg(message.toHtmlEscaped());
    qDebug() << "Writing: " << safe_msg;
    QTextCursor cursor = chat_box_text_messages_->textCursor();

    if (!cursor.atStart())
        cursor.insertBlock();
    cursor.insertHtml(safe_msg);
    qDebug() << "HTML: " << chat_box_text_messages_->toHtml();
}

这产生了完全相同的效果,因此要避免QT&#34;转换&#34; HTML,我认为我可以写出QT写的内容,但确实发生了同样的问题:

void PAChatClientUI::AddMessage(bool me, const QString& message)
{
    QString bgColor  = me ? "ffffff" : "f9564f";
    QString txtColor = me ? "0a0a0a" : "ffffff";

    QString to_append("\
        <p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; background-color:#" + bgColor + ";\"><span style=\" font-size:14px; color:#" + txtColor + "; background-color:#" + bgColor + ";\">" + message.toHtmlEscaped() + " </span></p>\
        <p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-size:3px;\">&zwnj; </span></p>\
    ");

    chat_box_text_messages_->append(to_append);
}

2 个答案:

答案 0 :(得分:0)

  

修改:此建议无法解决问题;它离开这里是为了完整。

QTextEdit在附加文本块时会对基础QTextDocument执行一些RichText魔术。尝试明确创建一个块并使用QTextCursor::insertHtml()代替QTextEdit::append()

QTextCursor cursor = m_ui.entryText->textCursor();

if(!cursor.atStart())
    cursor.insertBlock();
cursor.insertHtml(htmlText);

这也应该可以提高大量文本的效果。

答案 1 :(得分:0)

在将<div>打包到append()的公共调用中时,我能够重现此行为;将它们分成两个调用会产生预期的外观(在这里使用Qt 4.7)。