Воркед

This commit is contained in:
kromskii2 committed 2025-03-15 09:36:28 +07:00
1 parent ac32c55ab9
commit ee94d8e529
1138 files changed
+55771 -77901

No files matched your search

Binary file not shown.
+210 -168
View File
@@ -1,195 +1,237 @@
from PyQt6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout,
QLabel, QPushButton, QLineEdit, QTextEdit,
QSpinBox, QDoubleSpinBox, QComboBox)
from PyQt6.QtCore import Qt
from PyQt6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout,
QLabel, QPushButton, QLineEdit, QSpinBox,
QComboBox, QProgressBar)
from PyQt6.QtCore import Qt, pyqtSignal
from PyQt6.QtGui import QPixmap
import requests
from ..styles.style_constants import StyleConstants
from ..styles.icons import IconManager, IconType
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):
def __init__(self, model_manager, sampler_manager, size_preset_manager, parent=None):
super().__init__(parent)
self.theme_manager = ThemeManager.get_instance()
self.setup_content()
self.model_manager = model_manager
self.sampler_manager = sampler_manager
self.size_preset_manager = size_preset_manager
self.icon_manager = IconManager.get_instance()
self.setup_ui()
def setup_content(self):
"""Настройка содержимого страницы"""
colors = self.theme_manager.current_theme.get_colors()
spacing = self.theme_manager.current_theme.get_spacing()
def setup_ui(self):
# Верхняя панель с настройками
settings_panel = QHBoxLayout()
settings_panel.setContentsMargins(
StyleConstants.SPACING['lg'],
StyleConstants.SPACING['lg'],
StyleConstants.SPACING['lg'],
StyleConstants.SPACING['lg']
)
settings_panel.setSpacing(StyleConstants.SPACING['md'])
# Заголовок
header = QLabel("Генерация изображений")
header.setStyleSheet(f"""
QLabel {{
color: {colors['text']};
font-size: 18px;
font-weight: bold;
}}
""")
self.layout.addWidget(header)
# Выбор модели
model_label = QLabel("Модель:")
settings_panel.addWidget(model_label)
# Промпт
prompt_layout = QVBoxLayout()
self.model_combo = QComboBox()
self.model_combo.currentTextChanged.connect(self.on_model_changed)
settings_panel.addWidget(self.model_combo)
# Выбор сэмплера
sampler_label = QLabel("Сэмплер:")
settings_panel.addWidget(sampler_label)
self.sampler_combo = QComboBox()
self.sampler_combo.currentTextChanged.connect(self.on_sampler_changed)
settings_panel.addWidget(self.sampler_combo)
# Настройки размера
size_label = QLabel("Размер:")
settings_panel.addWidget(size_label)
self.width_spin = QSpinBox()
self.width_spin.setRange(64, 2048)
self.width_spin.setSingleStep(64)
self.width_spin.setValue(512)
settings_panel.addWidget(self.width_spin)
self.height_spin = QSpinBox()
self.height_spin.setRange(64, 2048)
self.height_spin.setSingleStep(64)
self.height_spin.setValue(512)
settings_panel.addWidget(self.height_spin)
settings_panel.addStretch()
self.layout.addLayout(settings_panel)
# Панель промптов
prompts_panel = QVBoxLayout()
prompts_panel.setContentsMargins(
StyleConstants.SPACING['lg'],
0,
StyleConstants.SPACING['lg'],
StyleConstants.SPACING['lg']
)
prompts_panel.setSpacing(StyleConstants.SPACING['md'])
# Позитивный промпт
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)
prompts_panel.addWidget(prompt_label)
prompt_layout.addWidget(prompt_label)
prompt_layout.addWidget(self.prompt_input)
self.layout.addLayout(prompt_layout)
self.prompt_edit = QLineEdit()
self.prompt_edit.setPlaceholderText("Опишите желаемое изображение...")
prompts_panel.addWidget(self.prompt_edit)
# Негативный промпт
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)
prompts_panel.addWidget(negative_prompt_label)
negative_prompt_layout.addWidget(negative_prompt_label)
negative_prompt_layout.addWidget(self.negative_prompt_input)
self.layout.addLayout(negative_prompt_layout)
self.negative_prompt_edit = QLineEdit()
self.negative_prompt_edit.setPlaceholderText("Опишите нежелательные элементы...")
prompts_panel.addWidget(self.negative_prompt_edit)
# Параметры генерации
params_layout = QHBoxLayout()
self.layout.addLayout(prompts_panel)
# Размер изображения
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)
# Панель генерации
generate_panel = QHBoxLayout()
generate_panel.setContentsMargins(
StyleConstants.SPACING['lg'],
0,
StyleConstants.SPACING['lg'],
StyleConstants.SPACING['lg']
)
generate_panel.setSpacing(StyleConstants.SPACING['md'])
# Количество шагов
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)
self.steps_spin.setPrefix("Шаги: ")
generate_panel.addWidget(self.steps_spin)
# 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)
self.cfg_spin = QSpinBox()
self.cfg_spin.setRange(1, 30)
self.cfg_spin.setValue(7)
self.cfg_spin.setPrefix("CFG: ")
generate_panel.addWidget(self.cfg_spin)
# Сэмплер
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.batch_size_spin = QSpinBox()
self.batch_size_spin.setRange(1, 4)
self.batch_size_spin.setValue(1)
self.batch_size_spin.setPrefix("Количество: ")
generate_panel.addWidget(self.batch_size_spin)
# Добавляем параметры на страницу
self.layout.addLayout(params_layout)
self.generate_btn = QPushButton("Сгенерировать")
self.generate_btn.setIcon(self.icon_manager.get_icon(IconType.GENERATE))
self.generate_btn.clicked.connect(self.generate_images)
generate_panel.addWidget(self.generate_btn)
# Кнопки управления
buttons_layout = QHBoxLayout()
buttons_layout.setSpacing(spacing.MEDIUM)
generate_panel.addStretch()
self.layout.addLayout(generate_panel)
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;
}}
# Прогресс-бар
progress_layout = QHBoxLayout()
progress_layout.setContentsMargins(
StyleConstants.SPACING['lg'],
0,
StyleConstants.SPACING['lg'],
StyleConstants.SPACING['lg']
)
self.progress_bar = QProgressBar()
self.progress_bar.setTextVisible(True)
self.progress_bar.setFormat("%p% - %v/%m шагов")
progress_layout.addWidget(self.progress_bar)
self.layout.addLayout(progress_layout)
# Область для результатов
result_layout = QVBoxLayout()
result_layout.setContentsMargins(
StyleConstants.SPACING['lg'],
0,
StyleConstants.SPACING['lg'],
StyleConstants.SPACING['lg']
)
self.result_label = QLabel()
self.result_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
result_layout.addWidget(self.result_label)
self.layout.addLayout(result_layout)
self.layout.addStretch()
# Обновляем UI
self.update_ui()
def update_ui(self):
"""Обновление UI после загрузки данных"""
# Обновляем список моделей
self.model_combo.clear()
for model in self.model_manager.get_models():
self.model_combo.addItem(model.title, model.name)
# Устанавливаем текущую модель
current_model = self.model_manager.get_current_model()
if current_model:
index = self.model_combo.findData(current_model.name)
if index >= 0:
self.model_combo.setCurrentIndex(index)
# Обновляем список сэмплеров
self.sampler_combo.clear()
for sampler in self.sampler_manager.get_samplers():
self.sampler_combo.addItem(sampler.title, sampler.name)
# Устанавливаем текущий сэмплер
current_sampler = self.sampler_manager.get_current_sampler()
if current_sampler:
index = self.sampler_combo.findData(current_sampler.name)
if index >= 0:
self.sampler_combo.setCurrentIndex(index)
def on_model_changed(self, model_title):
"""Обработка изменения модели"""
model_name = self.model_combo.currentData()
if model_name:
self.model_manager.switch_model(model_name)
def on_sampler_changed(self, sampler_title):
"""Обработка изменения сэмплера"""
sampler_name = self.sampler_combo.currentData()
if sampler_name:
self.sampler_manager.set_current_sampler(sampler_name)
def set_resolution(self, width: int, height: int):
"""Установка разрешения"""
self.width_spin.setValue(width)
self.height_spin.setValue(height)
def generate_images(self):
"""Генерация изображений"""
try:
# Получаем параметры
params = {
"prompt": self.prompt_edit.text(),
"negative_prompt": self.negative_prompt_edit.text(),
"steps": self.steps_spin.value(),
"cfg_scale": self.cfg_spin.value(),
"batch_size": self.batch_size_spin.value(),
"width": self.width_spin.value(),
"height": self.height_spin.value(),
"sampler_name": self.sampler_combo.currentData(),
}
QPushButton:hover {{
background-color: {colors['hover']};
}}
# Отправляем запрос
response = requests.post(
f"{self.model_manager.api_url}/sdapi/v1/txt2img",
json=params
)
QPushButton:pressed {{
background-color: {colors['active']};
}}
""")
if response.status_code == 200:
result = response.json()
# TODO: Отобразить сгенерированные изображения
print("Изображения успешно сгенерированы")
else:
print(f"Ошибка генерации: {response.status_code}")
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()
except Exception as e:
print(f"Ошибка при генерации: {str(e)}")
+124 -157
View File
@@ -1,178 +1,145 @@
from PyQt6.QtWidgets import (QLabel, QPushButton, QHBoxLayout,
QVBoxLayout, QLineEdit, QListWidget,
QListWidgetItem, QFrame)
from PyQt6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout,
QLabel, QPushButton, QLineEdit, QSpinBox,
QComboBox, QProgressBar, QScrollArea, 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
from ..styles.style_constants import StyleConstants
from ..styles.icons import IconManager, IconType
from ..styles.page import BasePage
class ModelItem(QFrame):
def __init__(self, model_name: str, parent=None):
class ModelCard(QFrame):
"""Карточка модели"""
def __init__(self, model, parent=None):
super().__init__(parent)
self.model_name = model_name
self.theme_manager = ThemeManager.get_instance()
self.model = model
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;
background-color: {StyleConstants.COLORS['dark']['surface']};
border-radius: {StyleConstants.RADIUS['md']}px;
padding: {StyleConstants.SPACING['md']}px;
margin-bottom: {StyleConstants.SPACING['md']}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;
color: {StyleConstants.COLORS['dark']['text']};
}}
""")
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']};
background-color: {StyleConstants.COLORS['primary']};
color: white;
border: none;
border-radius: {spacing.TINY}px;
padding: {spacing.SMALL}px {spacing.MEDIUM}px;
border-radius: {StyleConstants.RADIUS['sm']}px;
padding: {StyleConstants.SPACING['sm']}px {StyleConstants.SPACING['md']}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;
background-color: {StyleConstants.COLORS['secondary']};
}}
""")
# Добавляем тестовые модели
test_models = [
"stable-diffusion-v1-5",
"stable-diffusion-v2-1",
"stable-diffusion-xl-base-1.0"
]
layout = QVBoxLayout(self)
layout.setSpacing(StyleConstants.SPACING['sm'])
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)
# Название модели
title = QLabel(self.model.title)
title.setStyleSheet(f"""
font-size: {StyleConstants.FONTS['size']['lg']};
font-weight: {StyleConstants.FONTS['weight']['bold']};
""")
layout.addWidget(title)
self.layout.addWidget(self.models_list)
# Имя файла модели
name = QLabel(self.model.name)
name.setStyleSheet(f"""
font-size: {StyleConstants.FONTS['size']['sm']};
color: {StyleConstants.COLORS['dark']['text_secondary']};
""")
layout.addWidget(name)
# Кнопки управления
buttons_layout = QHBoxLayout()
select_btn = QPushButton("Выбрать")
select_btn.setIcon(IconManager.get_instance().get_icon(IconType.SUCCESS))
buttons_layout.addWidget(select_btn)
delete_btn = QPushButton("Удалить")
delete_btn.setIcon(IconManager.get_instance().get_icon(IconType.DELETE))
buttons_layout.addWidget(delete_btn)
buttons_layout.addStretch()
layout.addLayout(buttons_layout)
class ModelsPage(BasePage):
"""Страница управления моделями"""
def __init__(self, model_manager, parent=None):
super().__init__(parent)
self.model_manager = model_manager
self.setup_ui()
def setup_ui(self):
# Верхняя панель
top_panel = QHBoxLayout()
top_panel.setContentsMargins(
StyleConstants.SPACING['lg'],
StyleConstants.SPACING['lg'],
StyleConstants.SPACING['lg'],
StyleConstants.SPACING['lg']
)
top_panel.setSpacing(StyleConstants.SPACING['md'])
# Поиск
self.search_edit = QLineEdit()
self.search_edit.setPlaceholderText("Поиск моделей...")
top_panel.addWidget(self.search_edit)
# Кнопка обновления
refresh_btn = QPushButton("Обновить")
refresh_btn.setIcon(IconManager.get_instance().get_icon(IconType.REFRESH))
refresh_btn.clicked.connect(self.update_ui)
top_panel.addWidget(refresh_btn)
# Кнопка добавления
add_btn = QPushButton("Добавить")
add_btn.setIcon(IconManager.get_instance().get_icon(IconType.ADD))
top_panel.addWidget(add_btn)
top_panel.addStretch()
self.layout.addLayout(top_panel)
# Область прокрутки для моделей
scroll_area = QScrollArea()
scroll_area.setWidgetResizable(True)
scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
# Контейнер для карточек моделей
self.models_container = QWidget()
self.models_layout = QVBoxLayout(self.models_container)
self.models_layout.setContentsMargins(
StyleConstants.SPACING['lg'],
0,
StyleConstants.SPACING['lg'],
StyleConstants.SPACING['lg']
)
self.models_layout.setSpacing(0)
scroll_area.setWidget(self.models_container)
self.layout.addWidget(scroll_area)
# Обновляем UI
self.update_ui()
def update_ui(self):
"""Обновление списка моделей"""
# Очищаем контейнер
for i in reversed(range(self.models_layout.count())):
widget = self.models_layout.itemAt(i).widget()
if widget:
widget.deleteLater()
# Добавляем карточки моделей
for model in self.model_manager.get_models():
card = ModelCard(model)
self.models_layout.addWidget(card)
# Добавляем растягивающийся элемент в конец
self.models_layout.addStretch()