Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QTextEdit HTML font issue
QtWS25 Last Chance

QTextEdit HTML font issue

Scheduled Pinned Locked Moved Unsolved General and Desktop
qtextedithtml
5 Posts 4 Posters 1.5k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • W Offline
    W Offline
    wazzdaman
    wrote on last edited by wazzdaman
    #1

    Hello,

    I'd like to edit text loaded as HTML into QTextEdit and saved as HTML. I've noticed that font-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!

    JonBJ 1 Reply Last reply
    0
    • W wazzdaman

      Hello,

      I'd like to edit text loaded as HTML into QTextEdit and saved as HTML. I've noticed that font-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!

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by
      #2

      @wazzdaman
      Font families are listed in order or preference. The first one it can supply is used. Since you have Arial first in each case that will be used.

      W 1 Reply Last reply
      0
      • JonBJ JonB

        @wazzdaman
        Font families are listed in order or preference. The first one it can supply is used. Since you have Arial first in each case that will be used.

        W Offline
        W Offline
        wazzdaman
        wrote on last edited by
        #3

        @JonB Thanks for the fast answer! The order of use is clear to me. My question is why is Arial never replaced after font change?

        1 Reply Last reply
        0
        • S Offline
          S Offline
          Soren Juul
          wrote on last edited by
          #4

          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

          L 1 Reply Last reply
          0
          • S Soren Juul

            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

            L Offline
            L Offline
            lalula
            wrote on last edited by
            #5

            @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 setFontFamily

            here 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);
            
            1 Reply Last reply
            0

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved