Files
art/modules/model_manager.py
T
2025-03-15 09:36:28 +07:00

195 lines
7.1 KiB
Python

from PyQt6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout,
QComboBox, QPushButton, QLabel)
from PyQt6.QtCore import pyqtSignal
import requests
from typing import List, Dict
import os
from dotenv import load_dotenv
# Загружаем переменные окружения
load_dotenv()
class Model:
def __init__(self, name: str, title: str = None):
self.name = name
self.title = title or name
class ModelManager(QWidget):
model_changed = pyqtSignal(str)
def __init__(self, api_url, parent=None):
super().__init__(parent)
self.api_url = api_url
self.models = []
self.current_model = None
self.setup_ui()
self.load_models()
def setup_ui(self):
self.setStyleSheet("""
QWidget {
background-color: transparent;
}
QLabel {
color: #d4d4d4;
font-size: 13px;
font-weight: 500;
margin-right: 8px;
}
QComboBox {
background-color: #252526;
color: #d4d4d4;
border: 1px solid #3e3e3e;
border-radius: 6px;
padding: 6px 12px;
min-width: 200px;
font-size: 13px;
}
QComboBox:hover {
border-color: #565656;
}
QComboBox:focus {
border-color: #007acc;
}
QComboBox::drop-down {
border: none;
width: 20px;
}
QComboBox::down-arrow {
image: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTggMTFMNCBTTDEyIDUiIHN0cm9rZT0iI2Q0ZDRkNCIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4KPC9zdmc+);
}
QComboBox QAbstractItemView {
background-color: #252526;
color: #d4d4d4;
border: 1px solid #3e3e3e;
selection-background-color: #094771;
outline: none;
}
QPushButton {
background-color: #2d2d2d;
color: #d4d4d4;
border: 1px solid #3e3e3e;
border-radius: 6px;
padding: 6px 12px;
font-size: 13px;
}
QPushButton:hover {
background-color: #3e3e3e;
border-color: #565656;
}
QPushButton:pressed {
background-color: #565656;
}
""")
layout = QHBoxLayout(self)
layout.setContentsMargins(0, 0, 0, 0)
layout.setSpacing(8)
# Метка
label = QLabel("Модель:")
layout.addWidget(label)
# Выпадающий список моделей
self.model_combo = QComboBox()
self.model_combo.setFixedHeight(32)
self.model_combo.currentTextChanged.connect(self.on_model_changed)
layout.addWidget(self.model_combo)
# Кнопка обновления
refresh_button = QPushButton("🔄")
refresh_button.setFixedSize(32, 32)
refresh_button.setToolTip("Обновить список моделей")
refresh_button.clicked.connect(self.load_models)
layout.addWidget(refresh_button)
layout.addStretch()
def load_models(self):
"""Загрузить список доступных моделей"""
try:
response = requests.get(f"{self.api_url}/sdapi/v1/sd-models")
if response.status_code == 200:
models_data = response.json()
self.models = [
Model(model.get('title', ''), model.get('model_name', ''))
for model in models_data
]
# Получаем текущую модель
options_response = requests.get(f"{self.api_url}/sdapi/v1/options")
if options_response.status_code == 200:
current_model_name = options_response.json().get('sd_model_checkpoint')
self.current_model = next(
(model for model in self.models if model.name == current_model_name),
self.models[0] if self.models else None
)
# Обновляем UI
self.model_combo.clear()
for model in self.models:
self.model_combo.addItem(model.title)
# Устанавливаем текущую модель
if self.current_model:
index = self.model_combo.findText(self.current_model.title)
if index >= 0:
self.model_combo.setCurrentIndex(index)
except Exception as e:
print(f"Ошибка при загрузке моделей: {str(e)}")
self.models = []
self.current_model = None
def on_model_changed(self, model_title):
"""Обработка смены модели"""
model = next(
(m for m in self.models if m.title == model_title),
None
)
if model:
try:
response = requests.post(
f"{self.api_url}/sdapi/v1/options",
json={"sd_model_checkpoint": model.name}
)
if response.status_code == 200:
self.current_model = model
self.model_changed.emit(model.name)
except Exception as e:
print(f"Ошибка при смене модели: {str(e)}")
def update_api_url(self, new_url):
"""Обновить URL API"""
self.api_url = new_url
self.load_models()
def get_models(self):
"""Возвращает список доступных моделей"""
return self.models
def get_model_names(self):
"""Возвращает список имен моделей"""
return [model.name for model in self.models]
def get_current_model(self):
"""Возвращает текущую модель"""
return self.current_model
def switch_model(self, model_name: str) -> bool:
"""Переключение на другую модель"""
try:
response = requests.post(
f"{self.api_url}/sdapi/v1/options",
json={"sd_model_checkpoint": model_name}
)
if response.status_code == 200:
self.current_model = next(
(model for model in self.models if model.name == model_name),
None
)
return True
return False
except Exception as e:
print(f"Ошибка переключения модели: {str(e)}")
return False