Добавлен новый интерфейс с навигационной панелью и страницами для управления моделями, настройками и генерацией изображений. Реализованы стили для новых компонентов и добавлены функции для загрузки шрифтов и иконок. Обновлен основной класс окна для поддержки новых страниц.

This commit is contained in:
kromskii2 committed 2025-03-15 09:10:31 +07:00
1 parent df447a1ecf
commit ac32c55ab9
25 files changed
+1496 -476

No files matched your search

Binary file not shown.
+195
View File
@@ -0,0 +1,195 @@
from PyQt6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout,
QLabel, QPushButton, QLineEdit, QTextEdit,
QSpinBox, QDoubleSpinBox, QComboBox)
from PyQt6.QtCore import Qt
from ..styles.page import BasePage
from ..styles.theme import Colors, Spacing, Fonts
from ..styles.theme_manager import ThemeManager
class HomePage(BasePage):
def __init__(self, parent=None):
super().__init__(parent)
self.theme_manager = ThemeManager.get_instance()
self.setup_content()
def setup_content(self):
"""Настройка содержимого страницы"""
colors = self.theme_manager.current_theme.get_colors()
spacing = self.theme_manager.current_theme.get_spacing()
# Заголовок
header = QLabel("Генерация изображений")
header.setStyleSheet(f"""
QLabel {{
color: {colors['text']};
font-size: 18px;
font-weight: bold;
}}
""")
self.layout.addWidget(header)
# Промпт
prompt_layout = QVBoxLayout()
prompt_label = QLabel("Промпт:")
prompt_label.setStyleSheet(f"""
QLabel {{
color: {colors['text']};
font-size: 14px;
font-weight: 500;
}}
""")
self.prompt_input = QTextEdit()
self.prompt_input.setPlaceholderText("Опишите изображение, которое хотите сгенерировать...")
self.prompt_input.setMinimumHeight(100)
prompt_layout.addWidget(prompt_label)
prompt_layout.addWidget(self.prompt_input)
self.layout.addLayout(prompt_layout)
# Негативный промпт
negative_prompt_layout = QVBoxLayout()
negative_prompt_label = QLabel("Негативный промпт:")
negative_prompt_label.setStyleSheet(f"""
QLabel {{
color: {colors['text']};
font-size: 14px;
font-weight: 500;
}}
""")
self.negative_prompt_input = QTextEdit()
self.negative_prompt_input.setPlaceholderText("Опишите, что не должно появиться на изображении...")
self.negative_prompt_input.setMinimumHeight(100)
negative_prompt_layout.addWidget(negative_prompt_label)
negative_prompt_layout.addWidget(self.negative_prompt_input)
self.layout.addLayout(negative_prompt_layout)
# Параметры генерации
params_layout = QHBoxLayout()
# Размер изображения
size_layout = QVBoxLayout()
size_label = QLabel("Размер:")
size_label.setStyleSheet(f"""
QLabel {{
color: {colors['text']};
font-size: 14px;
font-weight: 500;
}}
""")
self.size_combo = QComboBox()
self.size_combo.addItems(["512x512", "768x768", "1024x1024"])
size_layout.addWidget(size_label)
size_layout.addWidget(self.size_combo)
params_layout.addLayout(size_layout)
# Количество шагов
steps_layout = QVBoxLayout()
steps_label = QLabel("Шаги:")
steps_label.setStyleSheet(f"""
QLabel {{
color: {colors['text']};
font-size: 14px;
font-weight: 500;
}}
""")
self.steps_spin = QSpinBox()
self.steps_spin.setRange(1, 150)
self.steps_spin.setValue(20)
steps_layout.addWidget(steps_label)
steps_layout.addWidget(self.steps_spin)
params_layout.addLayout(steps_layout)
# CFG Scale
cfg_layout = QVBoxLayout()
cfg_label = QLabel("CFG Scale:")
cfg_label.setStyleSheet(f"""
QLabel {{
color: {colors['text']};
font-size: 14px;
font-weight: 500;
}}
""")
self.cfg_spin = QDoubleSpinBox()
self.cfg_spin.setRange(1.0, 30.0)
self.cfg_spin.setValue(7.0)
self.cfg_spin.setSingleStep(0.5)
cfg_layout.addWidget(cfg_label)
cfg_layout.addWidget(self.cfg_spin)
params_layout.addLayout(cfg_layout)
# Сэмплер
sampler_layout = QVBoxLayout()
sampler_label = QLabel("Сэмплер:")
sampler_label.setStyleSheet(f"""
QLabel {{
color: {colors['text']};
font-size: 14px;
font-weight: 500;
}}
""")
self.sampler_combo = QComboBox()
self.sampler_combo.addItems(["Euler a", "Euler", "DPM++ 2M Karras"])
sampler_layout.addWidget(sampler_label)
sampler_layout.addWidget(self.sampler_combo)
params_layout.addLayout(sampler_layout)
# Добавляем параметры на страницу
self.layout.addLayout(params_layout)
# Кнопки управления
buttons_layout = QHBoxLayout()
buttons_layout.setSpacing(spacing.MEDIUM)
self.generate_button = QPushButton("Сгенерировать")
self.generate_button.setStyleSheet(f"""
QPushButton {{
min-width: 150px;
background-color: {colors['primary']};
color: white;
border: none;
border-radius: {spacing.TINY}px;
padding: {spacing.SMALL}px {spacing.MEDIUM}px;
}}
QPushButton:hover {{
background-color: {colors['hover']};
}}
QPushButton:pressed {{
background-color: {colors['active']};
}}
""")
self.clear_button = QPushButton("Очистить")
self.clear_button.setStyleSheet(f"""
QPushButton {{
min-width: 150px;
background-color: transparent;
color: {colors['primary']};
border: 1px solid {colors['primary']};
border-radius: {spacing.TINY}px;
padding: {spacing.SMALL}px {spacing.MEDIUM}px;
}}
QPushButton:hover {{
background-color: {colors['hover']};
color: white;
border: none;
}}
QPushButton:pressed {{
background-color: {colors['active']};
color: white;
border: none;
}}
""")
buttons_layout.addWidget(self.generate_button)
buttons_layout.addWidget(self.clear_button)
buttons_layout.addStretch()
self.layout.addLayout(buttons_layout)
# Растягиваем пространство
self.layout.addStretch()
+178
View File
@@ -0,0 +1,178 @@
from PyQt6.QtWidgets import (QLabel, QPushButton, QHBoxLayout,
QVBoxLayout, QLineEdit, QListWidget,
QListWidgetItem, QFrame)
from PyQt6.QtCore import Qt
from modules.styles.page import BasePage
from modules.styles.theme import Colors
from modules.styles.theme_manager import ThemeManager
class ModelItem(QFrame):
def __init__(self, model_name: str, parent=None):
super().__init__(parent)
self.model_name = model_name
self.theme_manager = ThemeManager.get_instance()
self.setup_ui()
def setup_ui(self):
"""Настройка UI элемента модели"""
colors = self.theme_manager.current_theme.get_colors()
spacing = self.theme_manager.current_theme.get_spacing()
layout = QHBoxLayout(self)
layout.setContentsMargins(8, 8, 8, 8)
# Название модели
name_label = QLabel(self.model_name)
name_label.setStyleSheet(f"color: {colors['text']};")
layout.addWidget(name_label)
# Растягиваем пространство
layout.addStretch()
# Кнопки управления
select_btn = QPushButton("Выбрать")
select_btn.setMinimumWidth(100)
select_btn.setStyleSheet(f"""
QPushButton {{
background-color: {colors['primary']};
color: white;
border: none;
border-radius: {spacing.TINY}px;
padding: {spacing.SMALL}px {spacing.MEDIUM}px;
}}
QPushButton:hover {{
background-color: {colors['hover']};
}}
QPushButton:pressed {{
background-color: {colors['active']};
}}
""")
layout.addWidget(select_btn)
delete_btn = QPushButton("Удалить")
delete_btn.setMinimumWidth(100)
delete_btn.setStyleSheet(f"""
QPushButton {{
background-color: {colors['error']};
color: white;
border: none;
border-radius: {spacing.TINY}px;
padding: {spacing.SMALL}px {spacing.MEDIUM}px;
}}
QPushButton:hover {{
background-color: {colors['hover']};
}}
QPushButton:pressed {{
background-color: {colors['active']};
}}
""")
layout.addWidget(delete_btn)
# Стили
self.setStyleSheet(f"""
QFrame {{
background-color: {colors['surface']};
border: 1px solid {colors['border']};
border-radius: {spacing.TINY}px;
}}
""")
class ModelsPage(BasePage):
def __init__(self, parent=None):
super().__init__(parent)
self.theme_manager = ThemeManager.get_instance()
self.setup_content()
def setup_content(self):
"""Настройка содержимого страницы"""
colors = self.theme_manager.current_theme.get_colors()
spacing = self.theme_manager.current_theme.get_spacing()
# Заголовок
header = QLabel("Модели")
header.setStyleSheet(f"""
QLabel {{
color: {colors['text']};
font-size: 24px;
font-weight: bold;
}}
""")
self.layout.addWidget(header)
# Поиск и добавление
search_layout = QHBoxLayout()
self.search_input = QLineEdit()
self.search_input.setPlaceholderText("Поиск моделей...")
self.search_input.setStyleSheet(f"""
QLineEdit {{
background-color: {colors['surface']};
color: {colors['text']};
border: 1px solid {colors['border']};
border-radius: {spacing.TINY}px;
padding: {spacing.SMALL}px;
}}
QLineEdit:focus {{
border: 1px solid {colors['primary']};
}}
""")
search_layout.addWidget(self.search_input)
self.add_btn = QPushButton("Добавить модель")
self.add_btn.setMinimumWidth(150)
self.add_btn.setStyleSheet(f"""
QPushButton {{
background-color: {colors['primary']};
color: white;
border: none;
border-radius: {spacing.TINY}px;
padding: {spacing.SMALL}px {spacing.MEDIUM}px;
}}
QPushButton:hover {{
background-color: {colors['hover']};
}}
QPushButton:pressed {{
background-color: {colors['active']};
}}
""")
search_layout.addWidget(self.add_btn)
self.layout.addLayout(search_layout)
# Список моделей
self.models_list = QListWidget()
self.models_list.setSpacing(8)
self.models_list.setStyleSheet(f"""
QListWidget {{
background-color: transparent;
border: none;
}}
QListWidget::item {{
padding: 0;
background-color: transparent;
}}
""")
# Добавляем тестовые модели
test_models = [
"stable-diffusion-v1-5",
"stable-diffusion-v2-1",
"stable-diffusion-xl-base-1.0"
]
for model in test_models:
item = QListWidgetItem(self.models_list)
model_widget = ModelItem(model)
item.setSizeHint(model_widget.sizeHint())
self.models_list.addItem(item)
self.models_list.setItemWidget(item, model_widget)
self.layout.addWidget(self.models_list)
+193
View File
@@ -0,0 +1,193 @@
from PyQt6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout,
QLabel, QPushButton, QLineEdit, QComboBox,
QSpinBox, QCheckBox, QFrame)
from PyQt6.QtCore import Qt
from ..styles.page import BasePage
from ..styles.theme import Colors, Spacing, Fonts
from ..styles.icons import IconManager, IconType
from ..styles.theme_manager import ThemeManager
class SettingsSection(QFrame):
def __init__(self, title: str, parent=None):
super().__init__(parent)
self.title = title
self.theme_manager = ThemeManager.get_instance()
self.setup_ui()
def setup_ui(self):
"""Настройка UI секции настроек"""
colors = self.theme_manager.current_theme.get_colors()
spacing = self.theme_manager.current_theme.get_spacing()
# Основной layout
layout = QVBoxLayout(self)
layout.setContentsMargins(16, 16, 16, 16)
layout.setSpacing(16)
# Заголовок секции
title_label = QLabel(self.title)
title_label.setStyleSheet(f"""
QLabel {{
color: {colors['text']};
font-size: 18px;
font-weight: bold;
}}
""")
layout.addWidget(title_label)
# Контейнер для содержимого
self.content_layout = QVBoxLayout()
self.content_layout.setSpacing(12)
layout.addLayout(self.content_layout)
# Стили
self.setStyleSheet(f"""
QFrame {{
background-color: {colors['surface']};
border: 1px solid {colors['border']};
border-radius: {spacing.MEDIUM}px;
}}
""")
class SettingsPage(BasePage):
def __init__(self, parent=None):
super().__init__(parent)
self.theme_manager = ThemeManager.get_instance()
self.setup_content()
def setup_content(self):
"""Настройка содержимого страницы"""
colors = self.theme_manager.current_theme.get_colors()
spacing = self.theme_manager.current_theme.get_spacing()
# Заголовок
header = QLabel("Настройки")
header.setStyleSheet(f"""
QLabel {{
color: {colors['text']};
font-size: 24px;
font-weight: bold;
}}
""")
self.layout.addWidget(header)
# API настройки
api_section = SettingsSection("API")
api_url_layout = QVBoxLayout()
api_url_label = QLabel("URL API:")
api_url_label.setStyleSheet(f"color: {colors['text']};")
self.api_url_input = QLineEdit()
self.api_url_input.setPlaceholderText("http://localhost:7860")
api_url_layout.addWidget(api_url_label)
api_url_layout.addWidget(self.api_url_input)
api_section.content_layout.addLayout(api_url_layout)
self.layout.addWidget(api_section)
# UI настройки
ui_section = SettingsSection("Интерфейс")
# Тема
theme_layout = QVBoxLayout()
theme_label = QLabel("Тема:")
theme_label.setStyleSheet(f"color: {colors['text']};")
self.theme_combo = QComboBox()
self.theme_combo.addItems(["Тёмная", "Светлая"])
theme_layout.addWidget(theme_label)
theme_layout.addWidget(self.theme_combo)
ui_section.content_layout.addLayout(theme_layout)
# Размер шрифта
font_size_layout = QVBoxLayout()
font_size_label = QLabel("Размер шрифта:")
font_size_label.setStyleSheet(f"color: {colors['text']};")
self.font_size_spin = QSpinBox()
self.font_size_spin.setRange(10, 24)
self.font_size_spin.setValue(14)
font_size_layout.addWidget(font_size_label)
font_size_layout.addWidget(self.font_size_spin)
ui_section.content_layout.addLayout(font_size_layout)
self.layout.addWidget(ui_section)
# Настройки генерации
generation_section = SettingsSection("Генерация")
# Качество по умолчанию
quality_layout = QVBoxLayout()
quality_label = QLabel("Качество по умолчанию:")
quality_label.setStyleSheet(f"color: {colors['text']};")
self.quality_combo = QComboBox()
self.quality_combo.addItems(["Низкое", "Среднее", "Высокое"])
quality_layout.addWidget(quality_label)
quality_layout.addWidget(self.quality_combo)
generation_section.content_layout.addLayout(quality_layout)
# Размер по умолчанию
size_layout = QVBoxLayout()
size_label = QLabel("Размер по умолчанию:")
size_label.setStyleSheet(f"color: {colors['text']};")
self.size_combo = QComboBox()
self.size_combo.addItems(["512x512", "768x768", "1024x1024"])
size_layout.addWidget(size_label)
size_layout.addWidget(self.size_combo)
generation_section.content_layout.addLayout(size_layout)
self.layout.addWidget(generation_section)
# Кнопки
buttons_layout = QHBoxLayout()
self.save_btn = QPushButton("Сохранить")
self.save_btn.setMinimumWidth(150)
self.save_btn.setStyleSheet(f"""
QPushButton {{
background-color: {colors['primary']};
color: white;
border: none;
border-radius: {spacing.TINY}px;
padding: {spacing.SMALL}px {spacing.MEDIUM}px;
}}
QPushButton:hover {{
background-color: {colors['hover']};
}}
QPushButton:pressed {{
background-color: {colors['active']};
}}
""")
buttons_layout.addWidget(self.save_btn)
self.reset_btn = QPushButton("Сбросить")
self.reset_btn.setMinimumWidth(150)
self.reset_btn.setStyleSheet(f"""
QPushButton {{
background-color: transparent;
color: {colors['primary']};
border: 1px solid {colors['primary']};
border-radius: {spacing.TINY}px;
padding: {spacing.SMALL}px {spacing.MEDIUM}px;
}}
QPushButton:hover {{
background-color: {colors['hover']};
color: white;
border: none;
}}
QPushButton:pressed {{
background-color: {colors['active']};
color: white;
border: none;
}}
""")
buttons_layout.addWidget(self.reset_btn)
buttons_layout.addStretch()
self.layout.addLayout(buttons_layout)
# Растягиваем пространство
self.layout.addStretch()