Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-80952

QFont::fromString() fails to properly set styleName() when used in QWidget

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Reported
    • Priority: P2: Important
    • Resolution: Unresolved
    • Affects Version/s: 5.13.2, 5.14.1
    • Fix Version/s: None
    • Component/s: GUI: Font handling
    • Labels:
      None
    • Environment:
    • Platform/s:
      Linux/X11

      Description

      On KDE, all QFont has a non-empty styleName() which generally returns "Regular".

      QFont has a bug where `QFont::fromString()` writes a new `styleName`, but if you use the resulting QFont in a QWidget, the QWidget still uses the Regular style name and font, due to https://bugreports.qt.io/browse/QTBUG-63792. If you pass fromString() a string generated from a bold/italic font, Qt may render the Regular font with faux bold or italic.

      The workaround is to run `font.setStyleName(font.styleName())` after calling `QFont::fromString()`. This looks like a no-op but causes Qt to recognize the style name properly.

      I have done some investigation at https://gitlab.com/nyanpasu64/qt-italic-bug-demo/tree/qfont-style (tag: qfont-style). The main program is at https://gitlab.com/nyanpasu64/qt-italic-bug-demo/blob/qfont-style/main.cpp , and you can swap `if(false)` and `if(true)` to change program behavior.

      I've paraphrased part of the test program which triggers this bug:

      QFont set_bold_italic;
      set_bold_italic.setFamily("Source Sans Pro");
      set_bold_italic.setBold(true);
      set_bold_italic.setItalic(true);
      
      // KDE, click Bold Italic, then OK.
      QFont font_dialog = QFontDialog::getFont(nullptr, set_bold_italic);
      
      QFont from_string;
      from_string.fromString("Source Sans Pro,10,-1,5,75,1,0,0,0,0,Bold Italic");
      if (using Qt 5.14) {
          from_string.setFamilies({"Source Sans Pro"});
      }
      
      // true
      qDebug() << (font_dialog == from_string);
      

      `QWidget::setFont(font_dialog)` results in true bold/italic, whereas `QWidget::setFont(from_string)` results in faux bold/italic. Which makes no sense since they're equal. If you run `from_string.setStyleName(from_string.styleName())`, then setting `from_string` to a QWidget will produce true bold/italic (like `font_dialog` does).

      Qt's behavior is slightly different on qtbase 5.13.2-3 (Manjaro Testing) and 5.14 Git (fe784abc80, hand-built). Only on 5.14 Git, `QFontDialog` returns a font with non-empty `families()` (which doesn't seem to affect the font resolution process). `families()` doesn't seem to do much other than participate in `==`, since it was recently introduced in Qt 5.13.

      I discovered this in https://bugreports.qt.io/browse/QTBUG-75027 but did not fully diagnose the issue then.

        Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

          Activity

            People

            Assignee:
            esabraha Eskil Abrahamsen Blomfeldt
            Reporter:
            anontt Anonymous (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Dates

              Created:
              Updated:

                Gerrit Reviews

                There are no open Gerrit changes