Как создать тему для 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/твоя_тема
Внутри этой папки будет вся структура темы.
Шаг 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/). Не придумывайте свои имена — приложение ожидает определённые названия переменных. Смотрите список в исходниках стандартной темы.
Шаг 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_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_easing_curve": "OutCubic",
"detail_page_easing_curve_exit": "InCubic"
}
Типы анимаций
| Параметр | Значения | Что делает |
|---|---|---|
card_animation_type |
"gradient", "scale" |
Градиентная обводка или увеличение карточки |
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"— начинается медленно, затем ускоряется
Попробуйте разные и посмотрите, что лучше подходит под стиль темы.
Шаг 4: Заполняем metainfo.ini
Этот файл рассказывает о теме пользователю. Создайте metainfo.ini в корне темы:
[Metainfo]
name_en = Cyberpunk Neon
name_ru = Киберпанк Неон
author = ВашеИмя
author_link = https://example.com
description_en = Futuristic theme with neon colors and dark background.
description_ru = Футуристичная тема с неоновыми цветами и тёмным фоном.
Переводы
Обязательно укажите названия и описания на разных языках:
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
│ └── platforms/
│ ├── steam.svg
│ └── epic.svg
├── ui_elements/
│ └── placeholder.png
└── screenshots/
└── main_window.png
Шаг 7: Тестируем тему
После того как всё готово:
- Перезапустите PortProtonQt — тема должна появиться в списке
- Проверьте все экраны — главное окно, детали, настройки, winetricks
- Пощёлкайте кнопки — убедитесь, что ховеры и фокусы работают
- Посмотрите на разных разрешениях — нет ли поломанной вёрстки
Удачи в создании темы!
Если что-то пойдёт не так — смотрите исходники встроенных тем в portprotonqt/themes/ для примеров.