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

问题描述:

我正在使用QTextEdit小部件向用户显示格式良好的聊天窗口。为了保持基本的测试我使用以下格式为我的html: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“转换”的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); 
} 

编辑:这个建议不解决问题;它是为了完整性而留在这里的。

QTextEdit当追加文本块时,对底层QTextDocument做了一些RichText魔术。尝试明确地创建块,并使用QTextCursor::insertHtml(),而不是QTextEdit::append()

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

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

这也应该提高大量文本的性能。

+0

不幸的是产生相同的行为 – Gizmo

+0

@Gizmo下一步尝试 - 我看看我自己的代码并添加了一个例子;然而,这应该解决块数和性能问题,我不确定它会帮助解决您的问题。 – Murphy

+0

我也试过了,它会产生相同的视觉效果:(QtWebKit对于这样简单的东西太过于矫枉过正... offtopic:任何其他的建议,至少使用这种颜色的简单聊天表示方法吗?我试过了SyntaxtHighlighter,但是它无法突出显示一条线的100%宽度 – Gizmo

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