diff --git a/main.py b/main.py index 67c98cf..30f371f 100644 --- a/main.py +++ b/main.py @@ -6,9 +6,9 @@ from time import sleep from PyQt6.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit, QPushButton, QComboBox, QSpinBox, QDoubleSpinBox, QProgressBar, - QScrollArea, QTextEdit, QFileDialog) + QScrollArea, QTextEdit, QFileDialog, QMenuBar, QMenu) from PyQt6.QtCore import Qt, QThread, pyqtSignal, QTimer -from PyQt6.QtGui import QPixmap, QImage +from PyQt6.QtGui import QPixmap, QImage, QAction from PIL import Image from io import BytesIO @@ -19,6 +19,7 @@ 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 class GenerationThread(QThread): progress_updated = pyqtSignal(float, str) @@ -68,8 +69,42 @@ class MainWindow(QMainWindow): self.prompt_window = None self.negative_prompt_window = None self.progress_timer = None + + # Создаем меню бар + self.create_menu_bar() + self.init_ui() + def create_menu_bar(self): + """Создание меню бара с настройками""" + menubar = QMenuBar(self) + menubar.setStyleSheet(""" + QMenuBar { + background-color: #2b2b2b; + color: #ffffff; + border-bottom: 1px solid #3b3b3b; + padding: 2px; + } + QMenuBar::item { + background-color: transparent; + padding: 8px 12px; + margin: 0; + border-radius: 4px; + } + QMenuBar::item:selected { + background-color: #3b3b3b; + } + QMenuBar::item:pressed { + background-color: #404040; + } + """) + + # Добавляем меню настроек + settings_menu = SettingsMenu(self) + menubar.addMenu(settings_menu) + + self.setMenuBar(menubar) + def init_ui(self): self.setWindowTitle("Stable Diffusion UI") self.setStyleSheet(""" diff --git a/modules/__pycache__/console_window.cpython-310.pyc b/modules/__pycache__/console_window.cpython-310.pyc index 9fbccca..645898d 100644 Binary files a/modules/__pycache__/console_window.cpython-310.pyc and b/modules/__pycache__/console_window.cpython-310.pyc differ diff --git a/modules/__pycache__/model_manager.cpython-310.pyc b/modules/__pycache__/model_manager.cpython-310.pyc index b068973..a4b83e9 100644 Binary files a/modules/__pycache__/model_manager.cpython-310.pyc and b/modules/__pycache__/model_manager.cpython-310.pyc differ diff --git a/modules/__pycache__/negative_prompt_categories.cpython-310.pyc b/modules/__pycache__/negative_prompt_categories.cpython-310.pyc index fa0e0d5..68c1b84 100644 Binary files a/modules/__pycache__/negative_prompt_categories.cpython-310.pyc and b/modules/__pycache__/negative_prompt_categories.cpython-310.pyc differ diff --git a/modules/__pycache__/negative_prompt_window.cpython-310.pyc b/modules/__pycache__/negative_prompt_window.cpython-310.pyc index 76153d7..cf39e33 100644 Binary files a/modules/__pycache__/negative_prompt_window.cpython-310.pyc and b/modules/__pycache__/negative_prompt_window.cpython-310.pyc differ diff --git a/modules/__pycache__/prompt_translations.cpython-310.pyc b/modules/__pycache__/prompt_translations.cpython-310.pyc index a3a02ec..b4b5d18 100644 Binary files a/modules/__pycache__/prompt_translations.cpython-310.pyc and b/modules/__pycache__/prompt_translations.cpython-310.pyc differ diff --git a/modules/__pycache__/prompt_window.cpython-310.pyc b/modules/__pycache__/prompt_window.cpython-310.pyc index 9574cb8..ebb6305 100644 Binary files a/modules/__pycache__/prompt_window.cpython-310.pyc and b/modules/__pycache__/prompt_window.cpython-310.pyc differ diff --git a/modules/__pycache__/sampler_manager.cpython-310.pyc b/modules/__pycache__/sampler_manager.cpython-310.pyc index 38e8da6..68863b4 100644 Binary files a/modules/__pycache__/sampler_manager.cpython-310.pyc and b/modules/__pycache__/sampler_manager.cpython-310.pyc differ diff --git a/modules/__pycache__/settings_menu.cpython-310.pyc b/modules/__pycache__/settings_menu.cpython-310.pyc new file mode 100644 index 0000000..ee181b2 Binary files /dev/null and b/modules/__pycache__/settings_menu.cpython-310.pyc differ diff --git a/modules/__pycache__/size_preset_manager.cpython-310.pyc b/modules/__pycache__/size_preset_manager.cpython-310.pyc index c240cae..7adb455 100644 Binary files a/modules/__pycache__/size_preset_manager.cpython-310.pyc and b/modules/__pycache__/size_preset_manager.cpython-310.pyc differ diff --git a/modules/__pycache__/size_presets.cpython-310.pyc b/modules/__pycache__/size_presets.cpython-310.pyc index 3318816..d0d6371 100644 Binary files a/modules/__pycache__/size_presets.cpython-310.pyc and b/modules/__pycache__/size_presets.cpython-310.pyc differ diff --git a/modules/settings_menu.py b/modules/settings_menu.py new file mode 100644 index 0000000..b70f117 --- /dev/null +++ b/modules/settings_menu.py @@ -0,0 +1,261 @@ +from PyQt6.QtWidgets import (QMenu, + QDialog, QVBoxLayout, QHBoxLayout, + QLabel, QLineEdit, QCheckBox, + QPushButton, QComboBox, QSpinBox) +from PyQt6.QtGui import QIcon, QAction, QActionGroup +from PyQt6.QtCore import Qt + +class SettingsMenu(QMenu): + def __init__(self, parent=None): + super().__init__("⚙️ Настройки", parent) + self.setStyleSheet(""" + QMenu { + background-color: #2b2b2b; + border: 1px solid #3b3b3b; + border-radius: 8px; + padding: 5px; + } + QMenu::item { + background-color: transparent; + padding: 8px 25px; + margin: 2px; + border-radius: 4px; + color: #ffffff; + font-size: 13px; + } + QMenu::item:selected { + background-color: #3b3b3b; + } + QMenu::separator { + height: 1px; + background-color: #3b3b3b; + margin: 5px 15px; + } + """) + self.setup_menu() + + def setup_menu(self): + # API настройки + api_action = QAction("🌐 API настройки", self) + api_action.triggered.connect(self.show_api_settings) + + # Настройки интерфейса + ui_action = QAction("🎨 Настройки интерфейса", self) + ui_action.triggered.connect(self.show_ui_settings) + + # Настройки генерации + generation_action = QAction("⚡ Настройки генерации", self) + generation_action.triggered.connect(self.show_generation_settings) + + # Горячие клавиши + hotkeys_action = QAction("⌨️ Горячие клавиши", self) + hotkeys_action.triggered.connect(self.show_hotkeys_settings) + + # Добавляем действия в меню + self.addAction(api_action) + self.addAction(ui_action) + self.addAction(generation_action) + self.addSeparator() + self.addAction(hotkeys_action) + + def show_api_settings(self): + dialog = APISettingsDialog(self.parent()) + dialog.exec() + + def show_ui_settings(self): + dialog = UISettingsDialog(self.parent()) + dialog.exec() + + def show_generation_settings(self): + dialog = GenerationSettingsDialog(self.parent()) + dialog.exec() + + def show_hotkeys_settings(self): + dialog = HotkeysSettingsDialog(self.parent()) + dialog.exec() + +class BaseSettingsDialog(QDialog): + def __init__(self, title, parent=None): + super().__init__(parent) + self.setWindowTitle(title) + self.setup_base_ui() + + def setup_base_ui(self): + self.setStyleSheet(""" + QDialog { + background-color: #2b2b2b; + min-width: 400px; + } + QLabel { + color: #ffffff; + font-size: 13px; + } + QLineEdit, QComboBox, QSpinBox { + background-color: #3b3b3b; + border: 1px solid #555555; + border-radius: 4px; + padding: 5px; + color: #ffffff; + min-width: 200px; + } + QPushButton { + background-color: #0d6efd; + color: white; + border: none; + border-radius: 4px; + padding: 8px 16px; + font-weight: bold; + min-width: 100px; + } + QPushButton:hover { + background-color: #0b5ed7; + } + QCheckBox { + color: #ffffff; + } + """) + + self.layout = QVBoxLayout(self) + self.layout.setSpacing(15) + self.layout.setContentsMargins(20, 20, 20, 20) + +class APISettingsDialog(BaseSettingsDialog): + def __init__(self, parent=None): + super().__init__("🌐 API настройки", parent) + self.setup_ui() + + def setup_ui(self): + # API URL + url_layout = QHBoxLayout() + url_label = QLabel("API URL:") + self.url_input = QLineEdit(self.parent().api_url_input.text()) + url_layout.addWidget(url_label) + url_layout.addWidget(self.url_input) + self.layout.addLayout(url_layout) + + # Кнопки + buttons_layout = QHBoxLayout() + save_button = QPushButton("Сохранить") + save_button.clicked.connect(self.save_settings) + cancel_button = QPushButton("Отмена") + cancel_button.clicked.connect(self.reject) + buttons_layout.addWidget(save_button) + buttons_layout.addWidget(cancel_button) + self.layout.addLayout(buttons_layout) + + def save_settings(self): + self.parent().api_url_input.setText(self.url_input.text()) + self.accept() + +class UISettingsDialog(BaseSettingsDialog): + def __init__(self, parent=None): + super().__init__("🎨 Настройки интерфейса", parent) + self.setup_ui() + + def setup_ui(self): + # Тема + theme_layout = QHBoxLayout() + theme_label = QLabel("Тема:") + self.theme_combo = QComboBox() + self.theme_combo.addItems(["Тёмная", "Светлая"]) + theme_layout.addWidget(theme_label) + theme_layout.addWidget(self.theme_combo) + self.layout.addLayout(theme_layout) + + # Размер шрифта + font_layout = QHBoxLayout() + font_label = QLabel("Размер шрифта:") + self.font_spin = QSpinBox() + self.font_spin.setRange(8, 24) + self.font_spin.setValue(14) + font_layout.addWidget(font_label) + font_layout.addWidget(self.font_spin) + self.layout.addLayout(font_layout) + + # Кнопки + buttons_layout = QHBoxLayout() + save_button = QPushButton("Сохранить") + save_button.clicked.connect(self.save_settings) + cancel_button = QPushButton("Отмена") + cancel_button.clicked.connect(self.reject) + buttons_layout.addWidget(save_button) + buttons_layout.addWidget(cancel_button) + self.layout.addLayout(buttons_layout) + + def save_settings(self): + # TODO: Применить настройки интерфейса + self.accept() + +class GenerationSettingsDialog(BaseSettingsDialog): + def __init__(self, parent=None): + super().__init__("⚡ Настройки генерации", parent) + self.setup_ui() + + def setup_ui(self): + # Качество по умолчанию + quality_layout = QHBoxLayout() + quality_label = QLabel("Качество по умолчанию:") + self.quality_combo = QComboBox() + self.quality_combo.addItems(["Низкое", "Среднее", "Высокое"]) + quality_layout.addWidget(quality_label) + quality_layout.addWidget(self.quality_combo) + self.layout.addLayout(quality_layout) + + # Размер по умолчанию + size_layout = QHBoxLayout() + size_label = QLabel("Размер по умолчанию:") + self.size_combo = QComboBox() + self.size_combo.addItems(["512x512", "768x512", "512x768"]) + size_layout.addWidget(size_label) + size_layout.addWidget(self.size_combo) + self.layout.addLayout(size_layout) + + # Кнопки + buttons_layout = QHBoxLayout() + save_button = QPushButton("Сохранить") + save_button.clicked.connect(self.save_settings) + cancel_button = QPushButton("Отмена") + cancel_button.clicked.connect(self.reject) + buttons_layout.addWidget(save_button) + buttons_layout.addWidget(cancel_button) + self.layout.addLayout(buttons_layout) + + def save_settings(self): + # TODO: Применить настройки генерации + self.accept() + +class HotkeysSettingsDialog(BaseSettingsDialog): + def __init__(self, parent=None): + super().__init__("⌨️ Горячие клавиши", parent) + self.setup_ui() + + def setup_ui(self): + # Генерация + generate_layout = QHBoxLayout() + generate_label = QLabel("Генерация:") + self.generate_input = QLineEdit("Ctrl+G") + generate_layout.addWidget(generate_label) + generate_layout.addWidget(self.generate_input) + self.layout.addLayout(generate_layout) + + # Открыть консоль + console_layout = QHBoxLayout() + console_label = QLabel("Открыть консоль:") + self.console_input = QLineEdit("Ctrl+`") + console_layout.addWidget(console_label) + console_layout.addWidget(self.console_input) + self.layout.addLayout(console_layout) + + # Кнопки + buttons_layout = QHBoxLayout() + save_button = QPushButton("Сохранить") + save_button.clicked.connect(self.save_settings) + cancel_button = QPushButton("Отмена") + cancel_button.clicked.connect(self.reject) + buttons_layout.addWidget(save_button) + buttons_layout.addWidget(cancel_button) + self.layout.addLayout(buttons_layout) + + def save_settings(self): + # TODO: Применить настройки горячих клавиш + self.accept() \ No newline at end of file