QFont изменение размера текста приложения

QFont устанавливается глобально через QApplication::setFont при старте программы.

Примечание: для чистоты эксперимента надо убрать все QFont в ui формах (файлы типа *.ui ) . Тогда будет намного проще разбираться.

Ищем и удаляем примерно такие включения :


         <property name="styleSheet">
          <string notr="true">font: 12pt &quot;MS Shell Dlg 2&quot;;
background-color: rgb(255, 255, 255);</string>
         </property>

Ищем и убираем установки фонтов :


           <property name="font">
            <font>
             <pointsize>10</pointsize>
            </font>
           </property>

Как в ui форме убрать установленный стиль нам не понятно до сих пор.

Примечание: даже убрав styleSheet в *.ui файле в ui_*.h все равно Qt сгенерирует :
connectFrDlg->setStyleSheet(QString::fromUtf8("")); - на это можно не обращать внимание.

Задемся полезной идеей как менять глобально фонты у всех окон в в процессе работы приложения, основаннному к примеру на QMainWindow.

То есть смысл в том , чтобы пользователь сам выбрал удобный для него размер фонта , стиль и т.д.

QFontDialog

Сначала описание одной проблемы , которую долго не могли решить.

Примечание: забегая вперед надо сказать, что фонт может меняться по setStyleSheet , а может по setFont....

Глюк /не глюк QT (4.8.1) проявляется в странном поведении например QFontDialog - он почему-то упорное Не возвращает выбранное в диалоге значение размера шрифта... Возвращает QFontDialog стабильно почему-то :

QFont( "Arial,-1,12,5,50,0,0,0,0,0" )  - это qDebug() << font

И еще визуально при выборе размера почему-то в окошке Sample измения размера не происходят, хотя например для стиля или типа шрифта отрабатыватся нормально.

Первым делом для изучения проблемы мы конечно унаследовались от QFontDialog , сделали Font_Dialog : QFontDialog . И видим , что сигнал Font_Dialog::currentFontChanged проходит при выборе значения в далоге нормально , мы его отлавливаем в классе Font_Dialog:

Font_Dialog : QFont( "Arial,26,-1,5,50,0,0,0,0,0" )

фотка 1

Правда смущает несколько ,что второй параметр [ в QFont( "Arial,26,-1,5,50,0,0,0,0,0" )] pointSize (26), а третий pixelSize (-1), но не в этом дело...

Примечание: судя по исходникам Qt - QFont вообще говоря работает только с pointSize , а pixelSize вообще не использует ни разу.

QFontDialog ::done

В процессе изучения сигналов испускаемых QFontDialog обнаружилось в функции QFontDialog ::done не понятное поведение (кстати можно отладчиком прямо в done зайти) , а именно :


void QFontDialog::done(int result)
{
    Q_D(QFontDialog);
    QDialog::done(result);
    if (result == Accepted) {
        // We check if this is the same font we had before, if so we emit currentFontChanged
        QFont selectedFont = currentFont();
        if(selectedFont != d->selectedFont)
            emit(currentFontChanged(selectedFont));   !!!!!!!!!
        d->selectedFont = selectedFont;
        emit fontSelected(d->selectedFont);
    } else
        d->selectedFont = QFont();
    if (d->receiverToDisconnectOnClose) {
        disconnect(this, SIGNAL(fontSelected(QFont)),
                   d->receiverToDisconnectOnClose, d->memberToDisconnectOnClose);
        d->receiverToDisconnectOnClose = 0;
    }
    d->memberToDisconnectOnClose.clear();
}

currentFont() это оказывается некий sampleEdit (приватный скрытый внутри
QFontDialog), который не что иное как QLineEdit - оконце (Sample) с примером выбранного шрифта.

Так вот почему-то в done currentFont возвращает всегда (у нас) размер 12 :

CurrentFont() : QFont( "Arial,-1,12,5,50,0,0,0,0,0" )

А d->selectedFont возвращает (у нас) значение , которое мы установили при старте программы :
QApplication::setFont(QFont("Arial", 14));

D->selectedFont: QFont( "Arial,14,-1,5,50,0,0,0,0,0" )

Оказывается ,что проблема в том , что сигнал currentFontChanged последний раз зачем-то выпускается в done и самое неприятное , что font у него совсем не вами выбранный , а некий с размером 12. Зачем так сделано не понятно...

Чтобы не править исходники Qt можно изменить Font_Dialog таким образом , чтобы сохранять выбранный фонт по сигналу currentFontChanged как переменную в Font_Dialog (назовем ее например myFont), но в done запретить сохранение в myFont. И это сработает .

Но появляется нюанс myFont будет вида QFont( "Arial,48,-1,5,50,0,0,0,0,0" ) , то есть pointSize 48, pixelSize -1. А надо наоборот. QFont( "Arial,-1,48,5,50,0,0,0,0,0" ).

Делом в том , что currentFontChanged до done , то в процессе выбора в диалоге , почему-то меняет местами pointSize и pixelSize . И это похоже нормально.

setFont

Изучим код для отрисовки выбранного шрифта . Он заканчивается в функции updateSampleFont. Тут мы добавили свой qDebug().


void QFontDialogPrivate::updateSampleFont(const QFont &newFont)
{
    Q_Q(QFontDialog);

#if  (defined(MY_DEBUG_FONT))
    qDebug() << "***** QFontDialogPrivate::updateSampleFont" << newFont;
#endif

    if (newFont != sampleEdit->font())
    {
        sampleEdit->setFont(newFont);
        emit q->currentFontChanged(newFont);
    }
}

Тут у нас оказывается , что setFont не меняет размер виджета , но меняет например стиль и тип фонта. Почему ? - непонятно....

Примечание: например в Qt creator на форме ui тоже есть выбор фонта и там кстати почему-то все работает нормально.

В нашем приложении на форме сделали кнопку для проверки поведения setFont и обнаружили , что setFont банально не работает как надо , то есть все параметры фонта устанавливаются нормально кроме размера....

Ну и остается добавить , что setStyleSheet работает нормально в части установки размера шрифта.

Момент истины

Случайно вдруг все заработало как надо и причина была установлена . Самое интересное , что мы использовали setStyleSheet в main.c и там в строке стилей забыли убрать такую строку:

QWidget { font-size: 12px;}

Оказывается именно в этом была причина того , что размер шрифта нигде не устанавливался. Кто бы мог подумать... То есть нельзя одновременно использовать setfont и SetStyleSheet в части фонтов!

Причем достаточно было написать по другому и все было бы ОК :

font-size: 12px; (то есть без QWidget ).

Вот и все, что нам сегодня хотелось рассказать о Qt 4.8.1. (2021г.)

Сохранение в реестре настроек фонтов пользователя и восстановление при старте программы.

QFontDialog нормально возвращает QFont.

При сохранения в реестре вроде логично использовать функцию toString :
В реестре запишется паримерно такая строка :
Arimo,9,-1,5,50,1,0,0,0,0
, но оказывается ее не достаточно...

То есть в реестре надо еще отдельно сохранять от QFont:

PointSize
pointSizeF
pixelSize
weight
bold
italic

И при старте программы их восстанавливать.

Далее для всех виджетов надо делать setFont , adjustSize .

На будущее зарекаемся в ui формах не трогать настройки стиля виджета , фонт и т.д. Все делаем в конструкторе класса формы только руками .