Как создать тему для PortProtonQt
Это руководство поможет вам создать собственную тему оформления для PortProtonQt. Вы узнаете, как настроить цвета, шрифты, анимации и другие визуальные элементы.
Предупреждение о безопасности
Важно: Сторонние темы могут представлять риски:
- Проверка безопасности — все темы проходят автоматическую проверку, которая блокирует опасные операции (доступ к файловой системе, сети, выполнение кода и т.д.). Однако это не 100% гарантия безопасности.
- Не поддерживаются разработчиками — использование сторонних тем на ваш страх и риск. Разработчики PortProtonQt не несут ответственности за проблемы, вызванные сторонними темами.
- Возможные уязвимости — темы содержат Python-код. Злоумышленник может найти способ обойти проверки.
- Отсутствие гарантий — тема может содержать ошибки, устареть или нарушать работу приложения.
- Проверяйте код — перед установкой внимательно изучайте
styles.pyи другие файлы темы.- Доверяйте источникам — загружайте темы только от проверенных авторов.
Рекомендация: Используйте встроенные темы или создавайте свои собственные.
Что нужно для создания темы
Для создания темы вам понадобятся:
- Папка с темой — место, где будут жить все файлы
styles.py— файл со стилями (QSS) и константамиmetainfo.ini— название, автор, описание- Скриншоты — чтобы показать, как тема выглядит
- Шрифты и иконки — опционально, если хотите кастомизацию
Всё это упаковывается в папку и кладётся в:
~/.local/share/PortProtonQT/themes/
Важно: Все константы (цвета, размеры, шрифты) и иконки нужно брать из встроенной темы
standart. Смотрите её структуру вportprotonqt/themes/standart/— это основной источник для копирования и адаптации под свою тему.
Шаг 1: Создаём папку темы
Придумайте название для темы (например, cyberpunk, minimal_dark, neon_vibe) и создайте папку:
mkdir -p ~/.local/share/PortProtonQT/themes/твоя_тема
Внутри этой папки будет вся структура темы.
Варианты темы (Light/Dark)
PortProtonQt поддерживает объединение светлой и тёмной версии темы в одну запись в списке тем.
Укажите связанные папки темы в metainfo.ini каждого варианта:
[Metainfo]
dark_variant = my_custom_theme
light_variant = my_custom_theme_light
Имена папок могут быть любыми допустимыми именами тем.
Если существуют обе указанные папки, приложение показывает отдельный выбор варианта: Dark, Light и Auto. Если существует только одна папка, выбор варианта скрывается, а доступная тема используется напрямую.
Auto используется как вариант по умолчанию. Он следует системной цветовой схеме
Оба варианта являются обычными темами и должны содержать собственный styles.py. Используйте THEME_INHERITS, если один вариант должен переиспользовать отсутствующие значения стилей из другой темы.
Важно: Если у темы есть оба варианта, добавьте
dark_variantиlight_variantвmetainfo.iniобеих папок, чтобы любая выбранная папка могла связаться с той же парой вариантов.
Шаг 2: Пишем стили (styles.py)
Что такое QSS?
QSS (Qt Style Sheets) — это язык стилей для приложений на Qt. Он работает как CSS в веб-разработке: вы задаёте цвета, размеры, шрифты и другие визуальные свойства для кнопок, окон и других элементов.
Если вы знакомы с CSS — QSS покажется вам понятным. Синтаксис почти идентичен:
QPushButton { color: red; background: white } QLineEdit { font-size: 16px }В отличие от обычного CSS, QSS работает с виджетами (QPushButton, QLabel, QFrame и т.д.), а не с HTML-тегами.
Вариант А: Простой (всё в одном файле)
Если тема небольшая — создайте styles.py прямо в корне темы и пишите всё там:
# Константы
font_family = "Play"
font_size_a = "16px"
border_radius_a = "10px"
color_primary = "#409EFF"
color_background = "#282a33"
# Стили
MAIN_WINDOW_STYLE = f"""
QMainWindow {{
background: {color_background};
font-family: {font_family};
font-size: {font_size_a};
}}
"""
GAME_CARD_STYLE = f"""
QFrame {{
background: {color_primary};
border-radius: {border_radius_a};
}}
"""
Вариант Б: Модульный (для больших тем)
Если тема разрастается — разбейте на подмодули. Создайте папку styles/ (или components/, как хотите) и внутри:
твоя_тема/
├── styles.py
├── metainfo.ini
├── fonts/
├── images/
└── styles/
├── __init__.py # Пустой файл, делает папку пакетом
├── constants.py # Все цвета, шрифты, размеры
├── base.py # Базовые стили (окна, кнопки)
├── game_card.py # Стили карточек игр
├── detail_page.py # Страница деталей игры
├── settings.py # Настройки
├── winetricks.py # Winetricks диалоги
└── theme_utils.py # Вспомогательные стили
В главном styles.py импортируйте всё:
# Относительные импорты (рекомендуется для пользовательских тем)
from .styles.constants import *
from .styles.base import *
from .styles.game_card import *
from .styles.detail_page import *
from .styles.settings import *
from .styles.winetricks import *
from .styles.theme_utils import *
В каждом подмодуле пишите свои константы и стили:
# styles/constants.py
# Цвета
color_primary = "#409EFF"
color_background = "#282a33"
color_text = "#FFFFFF"
color_disabled_text = "#888888"
# Размеры
font_size_a = "16px"
font_size_b = "24px"
border_radius_a = "10px"
border_radius_b = "15px"
# Тени
shadow_blur_radius = 20
shadow_color = "#00000099" # RGBA
# styles/base.py
from .constants import *
MAIN_WINDOW_STYLE = f"""
QMainWindow {{
background: {color_background};
font-family: {font_family};
font-size: {font_size_a};
color: {color_text};
}}
"""
BUTTON_STYLE = f"""
QPushButton {{
background: {color_primary};
color: {color_text};
border-radius: {border_radius_a};
padding: 8px 16px;
}}
QPushButton:hover {{
background: {color_primary_hover};
}}
QPushButton:disabled {{
background: {color_disabled};
color: {color_disabled_text};
}}
"""
Важно: Имена переменных для стилей (например,
MAIN_WINDOW_STYLE,BUTTON_STYLE,GAME_CARD_STYLE) нужно брать из встроенной темыstandart(portprotonqt/themes/standart/styles/). Не придумывайте свои имена — приложение ожидает определённые названия переменных. Смотрите список в исходниках стандартной темы.
Наследование стилей
Тема может наследовать отсутствующие переменные и функции стилей от другой темы через THEME_INHERITS в styles.py:
THEME_INHERITS = "classic"
Если THEME_INHERITS не указан, тема наследует стили от standart.
Режим сетки библиотеки
Вы можете управлять типом отображения карточек библиотеки прямо из темы через styles.py:
# "grid" (по умолчанию) или "list"
LIBRARY_LAYOUT_MODE = "grid"
grid: многоколоночная сетка карточек (формат лаунчера).list: горизонтальные карточки-строки (классическое поведение).
Это параметр уровня темы и не зависит от настроек приложения.
Режим отображения детальной страницы
Вы можете управлять отображением детальной страницы из темы через styles.py:
# "full" (по умолчанию) или "compact"
DETAIL_PAGE_LAYOUT_MODE = "full"
full: полный размер обложки, описание, бейджи, поддержка контроллера и данные HowLongToBeat.compact: уменьшенная обложка и упрощённое содержимое детальной страницы.
Экономный режим также принудительно включает компактное отображение детальной страницы.
Цветовые схемы терминала
Цветовые схемы терминала задаются отдельными .conf файлами в Kitty-style формате. Они полностью совместимы с темами Kitty: можно взять любую готовую цветовую схему Kitty и положить её в пользовательскую папку схем PortProtonQt.
Встроенные схемы находятся в portprotonqt/terminal_schemes/. Пользовательские схемы можно положить в:
~/.local/share/PortProtonQt/terminal_schemes/
Имя файла без .conf используется как имя схемы. Меню терминала показывает все доступные .conf файлы из пользовательской и встроенной директорий.
Пример:
foreground #d4d4d4
background #1e1e1e
cursor #bbbbbb
selection_foreground #ffffff
selection_background #264f78
background_opacity 1.0
cursor_shape block
enable_audio_bell no
color0 #000000
color1 #cd3131
color2 #0dbc79
color3 #e5e510
color4 #2472c8
color5 #bc3fbc
color6 #11a8cd
color7 #e5e5e5
font_size 14
font_family Monospace
Поддерживаемые параметры терминала:
foreground,background: основные цвета текста и фона.selection_foreground,selection_background: цвета выделенного текста.cursorилиcursor_color: цвет курсора.cursor_shape:block,beamилиunderline.enable_audio_bell:yes/no,true/false,on/offили1/0.background_opacity: прозрачность фона от0.0до1.0.font_size,font_family: настройки шрифта терминала.color0доcolor255: элементы ANSI-палитры.
Если cursor_shape не указан, терминал использует beam. Если enable_audio_bell не указан, звуковой сигнал выключен.
Шаг 3: Настраиваем анимации
В styles.py (или в отдельном файле, как удобно) определи словарь GAME_CARD_ANIMATION. Он управляет тем, как карточки игр анимируются при наведении, фокусе и переходе на детальную страницу.
GAME_CARD_ANIMATION = {
# Тип анимации карточки: "gradient" (вращающийся градиент) или "scale" (увеличение)
"card_animation_type": "gradient",
# Толщина рамки в пикселях
"default_border_width": 2, # Обычное состояние
"hover_border_width": 8, # При наведении
"focus_border_width": 12, # При фокусе (клавиатура)
"pulse_min_border_width": 8, # Пульсация: минимум
"pulse_max_border_width": 10, # Пульсация: максимум
# Длительность анимаций (в миллисекундах)
"thickness_anim_duration": 300, # Изменение толщины рамки
"pulse_anim_duration": 800, # Один цикл пульсации
"gradient_anim_duration": 3000, # Вращение градиента
# Углы вращения градиента
"gradient_start_angle": 360,
"gradient_end_angle": 0,
# Параметры для типов анимации fill, stripe и glow
"fill_color": color_primary,
"fill_alpha": 90,
"stripe_color": color_primary,
"stripe_alpha": 255,
"glow_base_alpha": 120,
"glow_pulse_alpha": 80,
# Градиент для обводки (список цветов с позициями)
"gradient_colors": [
{"position": 0, "color": "#00fff5"},
{"position": 0.33, "color": "#FF5733"},
{"position": 0.66, "color": "#9B59B6"},
{"position": 1, "color": "#00fff5"}
],
# Масштаб карточки (1.0 = 100%)
"default_scale": 1.0,
"hover_scale": 1.1, # 110% при наведении
"focus_scale": 1.05, # 105% при фокусе
"scale_anim_duration": 200,
# Плавность анимаций (названия из QEasingCurve.Type)
"thickness_easing_curve": "OutBack",
"thickness_easing_curve_out": "InBack",
"scale_easing_curve": "OutBack",
"scale_easing_curve_out": "InBack",
# Анимация детальной страницы
"detail_page_animation_type": "fade", # "fade", "slide_left", "slide_right", "bounce"
"detail_page_fade_duration": 350,
"detail_page_slide_duration": 500,
"detail_page_bounce_duration": 400,
"detail_page_fade_duration_exit": 350,
"detail_page_slide_duration_exit": 500,
"detail_page_bounce_duration_exit": 400,
"detail_page_easing_curve": "OutCubic",
"detail_page_easing_curve_exit": "InCubic"
}
Типы анимаций
| Параметр | Значения | Что делает |
|---|---|---|
card_animation_type |
"gradient", "scale", "fill", "stripe", "glow", "scale_fill" |
Тип анимации карточки при наведении или фокусе |
detail_page_animation_type |
"fade", "slide_left", "slide_right", "slide_up", "slide_down", "bounce" |
Как появляется детальная страница |
Градиенты
Цвета градиента задаются списком словарей. Каждый цвет имеет позицию от 0.0 до 1.0:
"gradient_colors": [
{"position": 0, "color": "#00fff5"}, # Начало (циан)
{"position": 0.5, "color": "#FF5733"}, # Середина (оранжевый)
{"position": 1, "color": "#00fff5"} # Конец (снова циан)
]
Кривые плавности (Easing Curves)
Это то, как анимация «чувствуется» — плавно, с разгоном, с отскоком и т.д.
Популярные варианты:
"OutBack"— плавное замедление с небольшим «отскоком» в конце"InOutQuad"— плавный разгон и замедление"OutCubic"— быстрое начало, плавное замедление"InBack"— начинается медленно, затем ускоряется
Попробуйте разные и посмотрите, что лучше подходит под стиль темы.
Анимации виртуальной клавиатуры
Настройки анимации виртуальной клавиатуры задаются константами темы:
virtual_keyboard_animation_type = "slide" # "slide", "fade", "slide_fade", "slide_bounce"
virtual_keyboard_slide_animation_duration = 160
virtual_keyboard_fade_animation_duration = 140
virtual_keyboard_slide_fade_animation_duration = 180
virtual_keyboard_slide_bounce_animation_duration = 220
Шаг 4: Заполняем metainfo.ini
Этот файл рассказывает о теме пользователю. Создайте metainfo.ini в корне темы:
[Metainfo]
dark_variant = cyberpunk
light_variant = cyberpunk_light
name_en = Cyberpunk Neon
name_ru = Киберпанк Неон
author = ВашеИмя
author_link = https://example.com
description_en = Futuristic theme with neon colors and dark background.
description_ru = Футуристичная тема с неоновыми цветами и тёмным фоном.
Варианты темы
Если у темы есть светлый и тёмный варианты, укажите dark_variant и light_variant в metainfo.ini обеих папок темы. Если вариант только один — эти поля можно не добавлять.
Переводы
Обязательно укажите названия и описания на разных языках:
name_en,name_ru,name_frи т.д.description_en,description_ru,description_frи т.д.
Приложение само выберет нужный язык в зависимости от системы пользователя. Если перевода нет — покажет английский.
Шаг 5: Добавляем скриншоты
Создайте папку images/screenshots/ внутри темы и положите туда скриншоты.
Важно: Скриншоты — это ваши собственные изображения. Не нужно копировать их из встроенной темы. Делайте скриншоты своей темы самостоятельно.
Называйте файлы как угодно, формат любой (PNG, JPG, WebP и т.д.). Скриншотьте всё, что считаете нужным для демонстрации темы — главное окно, отдельные элементы, анимации, настройки или любые другие детали, которые показывают особенности вашей темы.
Шаг 6: Шрифты и иконки (опционально)
Шрифты
Если хотите кастомный шрифт — положите файлы .ttf или .otf в папку fonts/:
твоя_тема/
└── fonts/
├── Play-Regular.ttf
├── Play-Bold.ttf
└── Roboto-Mono.ttf
В constants.py укажите:
font_family = "Play"
Иконки
Важно: Берите названия иконок из встроенной темы
standart(portprotonqt/themes/standart/images/icons/). Не придумывайте свои имена — используйте существующие файлы как референс.
Все иконки и изображения кладутся в images/. Система ищет иконки рекурсивно во всех подпапках, так что организовывайте как удобно:
твоя_тема/
└── images/
├── icons/
│ ├── actions/
│ │ ├── play.svg
│ │ ├── pause.svg
│ │ └── settings.svg
│ ├── navigation/
│ │ ├── arrow_left.svg
│ │ └── arrow_right.svg
│ ├── buttons/
│ ├── keyboards/
│ ├── controllers/
│ │ ├── xbox/
│ │ └── playstation/
│ └── platforms/
│ ├── steam.svg
│ └── epic.svg
├── ui_elements/
│ └── placeholder.png
└── screenshots/
└── main_window.png
Шаг 7: Тестируем тему
После того как всё готово:
- Перезапустите PortProtonQt — тема должна появиться в списке
- Проверьте все экраны — главное окно, детали, настройки, winetricks
- Пощёлкайте кнопки — убедитесь, что ховеры и фокусы работают
- Посмотрите на разных разрешениях — нет ли поломанной вёрстки
Удачи в создании темы!
Если что-то пойдёт не так — смотрите исходники встроенных тем в portprotonqt/themes/ для примеров.