QTextEdit HTML font issue
-
Hello,
I'd like to edit text loaded as HTML into
QTextEdit
and saved as HTML. I've noticed thatfont-family
holds multiple font names - the last one is added when I change the font but only the first one is taken in account, the rest is ignored.
The output looks kinda weird:<!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:'Arial'; font-size:42pt; 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;\"> <span style=\" font-family:'Arial','Modern';\">Text </span> <span style=\" font-family:'Arial','Bahnschrift Condensed';\">BAR</span></p></body></html>
Everything is shown as Arial text in this case. How can I fix this problem?
Here's my code (minus the UI/dtor part), using Qt5.15.6 on Windows 10:
#include <QColorDialog> #include <QMenuBar> #include <QPalette> #include "texteditordialog.h" TextEditorDialog::TextEditorDialog(const QString &text, QDialog *parent) : QDialog(parent, (QDialog().windowFlags() & ~Qt::WindowContextHelpButtonHint)) { createWidgets(); createLayout(); createConnections(); setWindowModality(Qt::ApplicationModal); setWindowTitle(tr("Edit text")); loadTextDocument(text); } void TextEditorDialog::createConnections() { connect(textEdit, &QTextEdit::selectionChanged, this, &TextEditorDialog::setFormatTools); connect(textEdit, &QTextEdit::cursorPositionChanged, this, &TextEditorDialog::setFormatTools); connect(undoAction, &QAction::triggered, textEdit, &QTextEdit::undo); connect(redoAction, &QAction::triggered, textEdit, &QTextEdit::redo); connect(cutAction, &QAction::triggered, textEdit, &QTextEdit::cut); connect(copyAction, &QAction::triggered, textEdit, &QTextEdit::copy); connect(pasteAction, &QAction::triggered, textEdit, &QTextEdit::paste); connect(selectAction, &QAction::triggered, textEdit, &QTextEdit::selectAll); connect(fontComboBox, &QFontComboBox::currentFontChanged, textEdit, &QTextEdit::setFontFamily); connect(fontSizeComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), [=](int index){ textEdit->setFontPointSize(qreal(4+index)); }); connect(boldAction, &QAction::toggled, this, [=](bool status){ textEdit->setFontWeight(status ? QFont::Bold : QFont::Normal); }); connect(italicAction, &QAction::toggled, textEdit, &QTextEdit::setFontItalic); connect(underlineAction, &QAction::toggled, textEdit, &QTextEdit::setFontUnderline); connect(fontColor, &ColorLabel::clicked, this, [=](){ QColorDialog dialog; dialog.adjustSize(); connect(&dialog, &QColorDialog::colorSelected, this, &TextEditorDialog::slotChangeFontColor); dialog.exec(); }); connect(backgroundColor, &ColorLabel::clicked, this, [=](){ QColorDialog dialog; dialog.adjustSize(); connect(&dialog, &QColorDialog::colorSelected, this, &TextEditorDialog::slotChangeBackgroundColor); dialog.exec(); }); connect(alignLAction, &QAction::triggered, this, [=](){ textEdit->setAlignment(Qt::AlignLeft); }); connect(alignCAction, &QAction::triggered, this, [=](){ textEdit->setAlignment(Qt::AlignCenter); }); connect(alignRAction, &QAction::triggered, this, [=](){ textEdit->setAlignment(Qt::AlignRight); }); connect(alignJAction, &QAction::triggered, this, [=](){ textEdit->setAlignment(Qt::AlignJustify); }); connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); } void TextEditorDialog::loadTextDocument(const QString &document) { textEdit->setHtml(document); setFormatTools(); } QString TextEditorDialog::saveTextDocument() { return textEdit->toHtml(); } void TextEditorDialog::setFormatTools() { blockSignals(true); fontComboBox->setCurrentFont(textEdit->currentFont()); fontSizeComboBox->setCurrentText(QString::number(textEdit->currentFont().pointSize())); boldAction->setChecked(textEdit->fontWeight() == QFont::Bold); italicAction->setChecked(textEdit->fontItalic()); underlineAction->setChecked(textEdit->fontUnderline()); fontColor->setColorSlot(textEdit->textColor()); backgroundColor->setColorSlot(textEdit->textBackgroundColor()); alignLAction->setChecked(textEdit->alignment() == Qt::AlignLeft); alignCAction->setChecked(textEdit->alignment() == Qt::AlignCenter); alignRAction->setChecked(textEdit->alignment() == Qt::AlignRight); alignJAction->setChecked(textEdit->alignment() == Qt::AlignJustify); blockSignals(false); } void TextEditorDialog::blockSignals(bool status) { fontComboBox->blockSignals(status); fontSizeComboBox->blockSignals(status); boldAction->blockSignals(status); italicAction->blockSignals(status); underlineAction->blockSignals(status); } void TextEditorDialog::slotCursorPositionChange() { setFormatTools(); } void TextEditorDialog::slotChangeFontColor(const QColor color) { textEdit->setTextColor(color); fontColor->setColorSlot(color); } void TextEditorDialog::slotChangeBackgroundColor(const QColor color) { textEdit->setTextBackgroundColor(color); backgroundColor->setColorSlot(color); }
Thanks!
-
I have run into the same problem using Qt 5.15.2.
Setting fontFamily(name) on QTextEdit will not change the font name, but append it as a secondary name, causing QTextEdit to not show the correct font, since it uses the first font name.This does not happen if QTextEdit is set with a plain text, but setHtml(ht) will cause the problem.
The following code example shows the problem without using UI.QTextEdit te; // Start by setting a text using Arial te.setFontFamily("Arial"); te.setText("ABC"); // The html output shows ... font-family:'Arial' QString html = te.toHtml(); qDebug() << "html 1" << html; // Then select all text and change font to Calibri QTextCursor crs = te.textCursor(); crs.movePosition(QTextCursor::Start); crs.movePosition(QTextCursor::End, QTextCursor::KeepAnchor); te.setTextCursor(crs); te.setFontFamily("Calibri"); // The html output is still good with ... font-family:'Calibri' html = te.toHtml(); qDebug() << "html 2" << html; // Change the font back to Arial te.setFontFamily("Arial"); // The html output is still good with ... font-family:'Arial' html = te.toHtml(); qDebug() << "html 3" << html; // Now set the text using the good html with Arial te.setHtml(html); // Again select all text and set the font to Calibri crs = te.textCursor(); crs.movePosition(QTextCursor::Start); crs.movePosition(QTextCursor::End, QTextCursor::KeepAnchor); te.setTextCursor(crs); te.setFontFamily("Calibri"); // Now the html output is bad with ... font-family:'Arial','Calibri' html = te.toHtml(); qDebug() << "html 4" << html;
The output from above code:
html 1 "<!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;"><span style=" font-family:'Arial';">ABC</span></p></body></html>"html 2 "<!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;"><span style=" font-family:'Calibri';">ABC</span></p></body></html>"
html 3 "<!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;"><span style=" font-family:'Arial';">ABC</span></p></body></html>"
html 4 "<!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;"><span style=" font-family:'Arial','Calibri';">ABC</span></p></body></html>"
where the last line with font-family:'Arial','Calibri' is not as expected.
It should only say Calibri to work correctly.Kind regards
Søren -
@Soren-Juul
I know this post is old, but ...I had a similar problem changing the font on a QtextCursor in QTextEdit
I solved it by using setFontFamilies instead of setFontFamilyhere a snip of my solution:
QTextCursor cursor = ui->textEdit->textCursor(); QTextCharFormat current = cursor.charFormat(); QStringList ffamily; ffamily.append(font); current.setFontFamilies(ffamily); cursor.setCharFormat(current);