MyTetra Share
Делитесь знаниями!
Как изменить размер шрифтов в Tk-приложениях для HiDPI мониторов?
Время создания: 27.02.2025 09:33
Текстовые метки: linux, dpi, tk, gui, библиотека, tcl/tk, tkinter, шрифт, иконка, размер, увеличить, изменить, font, xrdb, Xft, X11, X-сервер, HiDPI, монитор, экран, разрешение
Раздел: Компьютер - Программирование - Язык C++ (Си++) - Библиотека Qt - Графика
Запись: xintrea/mytetra_syncro/master/base/1740637996whica764kr/text.html на raw.github.com

При переходе на мониторы с большим разрешением 2K или 4K (так называемые HiDPI мониторы), в Linux возникает проблема с некоторыми программами, использующими те или иные графические библиотеки для отрисовки своего GUI-интерфейса. Эта проблема не обошла стороной и библиотеку Tk: в ней все надписи и кнопки на HiDPI мониторах выглядат очень мелкими. Как заставить Tk-приложения показывать адекватные элементы пользовательского интерфейса?


Сразу стоит сказать, что в общем случае никак. Все зависит от того, как написан код самого приложения.


Иногда в интерфейсе самого приложении есть настройки шрифтов. И в первую очередь надо попробовать покрутить их. Но даже эта возможность не всегда решает проблему: например, при удаленном подключении к X-серверу с экрана с другим DPI, приложение с выставленными шрифтами может выглядеть слишком крупно или слишком мелко. А перетыкание шрифта приведет к тому, что в дальнейшем уже при локальном запуске этого же приложения, шрифты будут неправильных размеров.


Некоторые приложения пытаются динамически изменять свой вид. Например, если в Pyhon-приложении с Tkinter есть примерно такой код:



import tkinter as tk


root = tk.Tk()


screen_width = root.winfo_screenwidth()

screen_height = root.winfo_screenheight()


if screen_width >= 2560 and screen_height >= 1440:


# Увеличиваем масштаб интерфейса

root.call('tk', 'scaling', 2.0)


# Устанавливаем шрифт глобально

root.option_add("*Font", "Arial 16")



... то определенное управление внешним видом в него заложено, и приложение будет выглядеть более-менее нормально, особенно если использовать установку xrdb-переменных (см. далее). Если же в приложении таких конструкций нет, то и установка xrdb-переменных будет влиять только на часть интерфейса: например, надписи будут увеличиваться, а кнопки - нет. В общем, простых путей для пользователей Tk-интерфейсов не предусмотрено.



Как повлиять на размер экранных элементов Tk-интерфейса?


Итак, как повлиять на размер экранных элементов, не меняя код самой Tk-программы?


Самый действенный способ - это использовать так называемые "ресурсы" X-сервера. Их еще называют X-ресурсами. По сути, это просто набор стандартизированных переменных и значений, существующий внутри X-сервера. На содержимое этого набора переменных можно влиять программой xrdb (X Resource Data Base).


Все строится на изменении значения DPI, которое хранится в переменной Xft.dpi. В разных Linux эта переменная может по-умолчанию существовать в X-ресурсах, а может и отсутствовать. В любом случае, если данная переменная появляется в X-ресурсах, то ее значение влияет на внешний вид X-приложений.


Предполагается, что Xft.dpi принадлежит одному экрану. Все приложения, запускаемые на экране, получают одно и то же значение Xft.dpi. Если к компьютеру подключено два и более мониторов, то считается, что пользователь работает с одним большим виртуальным экраном, какая бы плотность пикселей у этих разных мониторов ни была. В этом смысле можно говорить, что значение Xft.dpi существует в пределах одной пользовательской сессии.



Получение значения Xft.dpi


В любом случае, прежде чем изменять Xft.dpi, надо узнать какое у него значение по-умолчанию, чтобы было понятно вокруг какого диапазона значений надо плясать, и чтобы была возможность вернуть значение в первоначальное состояние. Для этого, от обычного пользователя, надо дать команду:



xrdb -query



В ответ будет выдан список переменных, например такой:



*customization: -color

Xcursor.size: 16

Xft.dpi: 108



Как было сказано выше, в этом списке может не быть переменной Xft.dpi. В этом случае пользователю не повезло, потому что в интерфейсе xrdb предусмотрено добавление переменной, но не предусмотрено удаление переменной (чтобы была возможность вернуть систему в начальное состояние). Вот такие гении писали инструментарий. Имеется только полное удаление всех ресурсов через опцию -remove. Хорошая новость заключается в том, что динамические изменения в X-ресурсах сохраняются только до перезапуска X-сервера.


Еще информация: пользователи, копавшие код X-сервера руками, говорят, что если ресурс Xft.dpi на X-сервере отсутствует, то библиотека Xft использует дефолтное значение 96.



Для справки


Стандартный ряд значений DPI следующий:

96 (100%), 120 (125%), 144 (150%), 168 (175%), 192 (200%).



Как изменить значение Xft.dpi


Для того, чтобы перед запуском Tk-программы установить заданное значение Xft.dpi, можно воспользоваться командой:



export XRESOURCES="Xft.dpi: 192"; xrdb -merge <<< "$XRESOURCES"



Далее можно запустить саму Tk-программу и посмотреть как она выглядит. Когда параметры подобраны, эту настройку можно поместить в скрипт запуска нужного приложения. Только следует помнить, что изменение Xft.dpi повлияет на запуск всех последующих приложений до зовершения сессии.


Поэтому для запуска можно написать более сложный скрипт, который выясняет начальную настройку DPI, устанавливает нужное DPI, запускает программу в отвязке от терминала, и восстанавливает начальную настройку DPI.


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



Особенности


Разные версии одной и той же программы могут по разному реагировать на установку Xft.dpi. Например, в git gui версии 0.20.0.44 установка DPI влияет только на шрифт меню, текстовых полей и надписей, но не влияет на шрифт кнопок. А в версии 0.21.0.93 надписи на кнопках меняются в сответствии с заданным DPI. В общем, как ни крути, управление экранными элементами через выставление DPI очень индивидуально.


Так же в этом разделе:
 
MyTetra Share v.0.67
Яндекс индекс цитирования