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

221 lines
8.4 KiB
Python

import sys
import json
import base64
import requests
import os
from time import sleep
from PyQt6.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout,
QHBoxLayout, QLabel, QLineEdit, QPushButton,
QComboBox, QSpinBox, QDoubleSpinBox, QProgressBar,
QScrollArea, QTextEdit, QFileDialog, QMenuBar, QMenu)
from PyQt6.QtCore import Qt, QThread, pyqtSignal, QTimer
from PyQt6.QtGui import QPixmap, QImage, QAction, QFontDatabase, QFont
from PIL import Image
from io import BytesIO
from pathlib import Path
from dotenv import load_dotenv
# Загружаем переменные окружения
load_dotenv()
# Импортируем модули
from modules.console_window import ConsoleWindow
from modules.model_manager import ModelManager
from modules.sampler_manager import SamplerManager
from modules.prompt_window import PromptWindow
from modules.negative_prompt_window import NegativePromptWindow
from modules.size_preset_manager import SizePresetManager
from modules.settings_menu import SettingsMenu
from modules.styles.base_window import BaseWindow
from modules.styles.navigation import NavigationPanel
from modules.styles.page import PageContainer
from modules.pages.home_page import HomePage
from modules.pages.models_page import ModelsPage
from modules.pages.settings_page import SettingsPage
from scripts.download_resources import download_font
class GenerationThread(QThread):
progress_updated = pyqtSignal(float, str)
generation_complete = pyqtSignal(list)
error_occurred = pyqtSignal(str)
def __init__(self, api_url, params):
super().__init__()
self.api_url = api_url
self.params = params
self.is_generating = False
def run(self):
try:
self.is_generating = True
self.progress_updated.emit(0, "Начало генерации...")
# Отправляем запрос на генерацию
response = requests.post(f"{self.api_url}/sdapi/v1/txt2img", json=self.params)
if response.status_code != 200:
self.error_occurred.emit(f"Ошибка API: {response.status_code}")
return
# Получаем результат
result = response.json()
images = result.get('images', [])
if not images:
self.error_occurred.emit("Не удалось получить изображения")
return
self.generation_complete.emit(images)
except Exception as e:
self.error_occurred.emit(f"Ошибка: {str(e)}")
finally:
self.is_generating = False
def stop(self):
self.is_generating = False
class MainWindow(BaseWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Stable Diffusion UI")
self.setMinimumSize(1200, 800)
# Получаем URL API из переменных окружения
self.api_url = os.getenv('SD_API_URL', 'http://localhost:3000')
# Инициализируем менеджеры
self.model_manager = ModelManager(api_url=self.api_url)
self.sampler_manager = SamplerManager(api_url=self.api_url)
self.size_preset_manager = SizePresetManager()
# Инициализируем окна
self.prompt_window = PromptWindow()
self.negative_prompt_window = NegativePromptWindow()
self.console_window = ConsoleWindow()
self.setup_ui()
def setup_ui(self):
# Загружаем шрифт
font_path = Path("resources/fonts/InterVariable.ttf")
if not font_path.exists():
download_font()
font_id = QFontDatabase.addApplicationFont(str(font_path))
if font_id != -1:
font_family = QFontDatabase.applicationFontFamilies(font_id)[0]
app_font = QFont(font_family)
QApplication.setFont(app_font)
# Создаем центральный виджет
central_widget = QWidget()
self.setCentralWidget(central_widget)
main_layout = QVBoxLayout(central_widget)
main_layout.setContentsMargins(0, 0, 0, 0)
main_layout.setSpacing(0)
# Создаем верхнюю панель
top_panel = QHBoxLayout()
# Кнопки для окон промптов
prompt_btn = QPushButton("Библиотека промптов")
prompt_btn.clicked.connect(self.show_prompt_window)
top_panel.addWidget(prompt_btn)
negative_prompt_btn = QPushButton("Негативные промпты")
negative_prompt_btn.clicked.connect(self.show_negative_prompt_window)
top_panel.addWidget(negative_prompt_btn)
# Пресеты разрешения
resolution_combo = QComboBox()
resolution_combo.addItems(self.size_preset_manager.get_preset_names())
resolution_combo.currentTextChanged.connect(self.on_resolution_changed)
top_panel.addWidget(resolution_combo)
# Кнопка консоли
console_btn = QPushButton("Консоль")
console_btn.clicked.connect(self.show_console)
top_panel.addWidget(console_btn)
top_panel.addStretch()
main_layout.addLayout(top_panel)
# Создаем горизонтальный layout для навигации и контента
content_layout = QHBoxLayout()
# Добавляем навигационную панель
self.nav_panel = NavigationPanel()
content_layout.addWidget(self.nav_panel)
# Создаем контейнер для страниц
self.page_container = PageContainer()
content_layout.addWidget(self.page_container)
main_layout.addLayout(content_layout)
# Добавляем страницы
self.home_page = HomePage(
model_manager=self.model_manager,
sampler_manager=self.sampler_manager,
size_preset_manager=self.size_preset_manager
)
self.models_page = ModelsPage(self.model_manager)
self.settings_page = SettingsPage()
self.page_container.add_page("home", self.home_page)
self.page_container.add_page("models", self.models_page)
self.page_container.add_page("settings", self.settings_page)
# Подключаем сигнал смены страницы
self.nav_panel.page_changed.connect(self.switch_page)
# Показываем домашнюю страницу по умолчанию
self.page_container.show_page("home")
# Загружаем данные
self.load_data()
def load_data(self):
"""Загрузка данных с сервера"""
try:
# Загружаем список моделей
self.model_manager.load_models()
# Загружаем список сэмплеров
self.sampler_manager.load_samplers()
# Обновляем интерфейс
self.home_page.update_ui()
self.models_page.update_ui()
except Exception as e:
self.console_window.log(f"Ошибка загрузки данных: {str(e)}", "ERROR")
def show_prompt_window(self):
"""Показать окно промптов"""
self.prompt_window.show()
def show_negative_prompt_window(self):
"""Показать окно негативных промптов"""
self.negative_prompt_window.show()
def show_console(self):
"""Показать консоль"""
self.console_window.show()
def on_resolution_changed(self, preset_name: str):
"""Обработка изменения пресета разрешения"""
preset = self.size_preset_manager.get_preset(preset_name)
if preset:
self.home_page.set_resolution(preset.width, preset.height)
def switch_page(self, page_name):
self.page_container.show_page(page_name)
def main():
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())
if __name__ == "__main__":
main()