Как создать тему для PortProtonQt

Как создать тему для PortProtonQt

Это руководство поможет вам создать собственную тему оформления для PortProtonQt. Вы узнаете, как настроить цвета, шрифты, анимации и другие визуальные элементы.


Предупреждение о безопасности

Важно: Сторонние темы могут представлять риски:

  • Проверка безопасности — все темы проходят автоматическую проверку, которая блокирует опасные операции (доступ к файловой системе, сети, выполнение кода и т.д.). Однако это не 100% гарантия безопасности.
  • Не поддерживаются разработчиками — использование сторонних тем на ваш страх и риск. Разработчики PortProtonQt не несут ответственности за проблемы, вызванные сторонними темами.
  • Возможные уязвимости — темы содержат Python-код. Злоумышленник может найти способ обойти проверки.
  • Отсутствие гарантий — тема может содержать ошибки, устареть или нарушать работу приложения.
  • Проверяйте код — перед установкой внимательно изучайте styles.py и другие файлы темы.
  • Доверяйте источникам — загружайте темы только от проверенных авторов.

Рекомендация: Используйте встроенные темы или создавайте свои собственные.


Что нужно для создания темы

Для создания темы вам понадобятся:

  1. Папка с темой — место, где будут жить все файлы
  2. styles.py — файл со стилями (QSS) и константами
  3. metainfo.ini — название, автор, описание
  4. Скриншоты — чтобы показать, как тема выглядит
  5. Шрифты и иконки — опционально, если хотите кастомизацию

Всё это упаковывается в папку и кладётся в:

~/.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: Тестируем тему

После того как всё готово:

  1. Перезапустите PortProtonQt — тема должна появиться в списке
  2. Проверьте все экраны — главное окно, детали, настройки, winetricks
  3. Пощёлкайте кнопки — убедитесь, что ховеры и фокусы работают
  4. Посмотрите на разных разрешениях — нет ли поломанной вёрстки

Удачи в создании темы!

Если что-то пойдёт не так — смотрите исходники встроенных тем в portprotonqt/themes/ для примеров.