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

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

Cразу рекомендация посмотрите: pointSize - pixelSize

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

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

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

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

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

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

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

Проблема 1

setFont для QDialog не распространяется на виджеты внутри самого QDialog. То есть каждому виджету надо устанавливать индивидуально. Можно это делать в конструкторе QDialog 

    ui->lbl_input->setFont( appDef::appDoubleFont);
    ui->ledt_input->setFont( appDef::appDoubleFont);
    ui->pushButton->setFont( appDef::appDoubleFont);
    ui->pushButton_2->setFont( appDef::appDoubleFont);

или снаружи при создании QDialog до show (или exec):

    input_Dlg inputDlg (parent ,
                        header,
                        label ,
                        defaultVal,
                        validator);

//    inputDlg.setFont( appDef::appDoubleFont );
//    inputDlg.update();

    foreach(QWidget * widg, inputDlg.findChildren<QWidget *>())
    {
        widg->setFont( appDef::appDoubleFont ); // важно
    }

    inputDlg.updateGeometry(); // !!!!! важно

    inputDlg.adjustSize();
    qDebug() << inputDlg.sizeHint();
    inputDlg.setFixedSize( inputDlg.sizeHint() );

    inputDlg.show();

История одной ошибки

Далее старые писанины: в основном смысл в том, что надо внимательно думать, что ты пишешь в setStyleSheet и какие неожиданные последствия могут появиться.

Задаемся полезной идеей как менять глобально фонты у всех окон в в процессе работы приложения, основанному к примеру на 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 формах не трогать настройки стиля виджета , фонт и т.д. Все делаем в конструкторе класса формы только руками .