Воркед
This commit is contained in:
1 parent
ac32c55ab9
commit
ee94d8e529
1138 files changed
+55771
-77901
No files matched your search
Binary file not shown.
Binary file not shown.
+210
-168
@@ -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
@@ -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()
|
||||
Reference in new issue
Block a user