From 4b16298d0583500434347cb19607eb17aa8aef33 Mon Sep 17 00:00:00 2001 From: kromskii2 <146603192+kromskii2@users.noreply.github.com> Date: Fri, 14 Mar 2025 19:34:01 +0700 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=20=D0=BC=D0=BE=D0=B4=D1=83=D0=BB=D1=8C=20=D0=B3=D0=BE?= =?UTF-8?q?=D1=82=D0=BE=D0=B2=D1=8B=D1=85=20=D0=BF=D1=80=D0=BE=D0=BC=D0=BF?= =?UTF-8?q?=D1=82=D0=BE=D0=B2:=20=D1=81=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD?= =?UTF-8?q?=D0=BE=20=D0=BE=D0=BA=D0=BD=D0=BE=20=D1=81=20=D0=BA=D0=B0=D1=82?= =?UTF-8?q?=D0=B5=D0=B3=D0=BE=D1=80=D0=B8=D1=8F=D0=BC=D0=B8=20=D0=BF=D1=80?= =?UTF-8?q?=D0=BE=D0=BC=D0=BF=D1=82=D0=BE=D0=B2,=20=D0=B4=D0=BE=D0=B1?= =?UTF-8?q?=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=20=D0=BF=D0=BE=D0=B8=D1=81=D0=BA?= =?UTF-8?q?,=20=D1=80=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=BE=D0=B2=D0=B0?= =?UTF-8?q?=D0=BD=D0=BE=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D0=BF=D1=80=D0=BE=D0=BC=D0=BF=D1=82=D0=BE=D0=B2?= =?UTF-8?q?=20=D0=B2=20=D0=BE=D1=81=D0=BD=D0=BE=D0=B2=D0=BD=D0=BE=D0=B5=20?= =?UTF-8?q?=D0=BF=D0=BE=D0=BB=D0=B5=20=D0=B2=D0=B2=D0=BE=D0=B4=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.py | 23 ++++++ modules/prompt_categories.py | 64 +++++++++++++++++ modules/prompt_window.py | 136 +++++++++++++++++++++++++++++++++++ 3 files changed, 223 insertions(+) create mode 100644 modules/prompt_categories.py create mode 100644 modules/prompt_window.py diff --git a/main.py b/main.py index e47fd40..570acb3 100644 --- a/main.py +++ b/main.py @@ -16,6 +16,7 @@ from io import BytesIO from modules.console_window import ConsoleWindow from modules.model_manager import ModelManager from modules.sampler_manager import SamplerManager +from modules.prompt_window import PromptWindow class GenerationThread(QThread): progress_updated = pyqtSignal(float, str) @@ -62,6 +63,7 @@ class MainWindow(QMainWindow): super().__init__() self.api_url = "http://localhost:7860" # URL по умолчанию self.console_window = None + self.prompt_window = None self.progress_timer = None self.init_ui() @@ -240,6 +242,11 @@ class MainWindow(QMainWindow): self.console_button.clicked.connect(self.toggle_console) settings_layout.addWidget(self.console_button) + # Добавляем кнопку промптов + self.prompt_button = QPushButton("Готовые промпты") + self.prompt_button.clicked.connect(self.toggle_prompt_window) + settings_layout.addWidget(self.prompt_button) + # Кнопка генерации self.generate_button = QPushButton("Сгенерировать") self.generate_button.clicked.connect(self.start_generation) @@ -294,6 +301,22 @@ class MainWindow(QMainWindow): self.console_window.log(message) print(message) + def toggle_prompt_window(self): + """Открыть/закрыть окно с промптами""" + if self.prompt_window is None: + self.prompt_window = PromptWindow(parent=self) + self.prompt_window.prompt_selected.connect(self.add_prompt) + self.prompt_window.show() + else: + self.prompt_window.close() + + def add_prompt(self, prompt): + """Добавить промпт в поле ввода""" + current_text = self.prompt_input.toPlainText() + if current_text: + current_text += ", " + self.prompt_input.setText(current_text + prompt) + def start_generation(self): self.generate_button.setEnabled(False) self.progress_bar.setValue(0) diff --git a/modules/prompt_categories.py b/modules/prompt_categories.py new file mode 100644 index 0000000..b8ec6e9 --- /dev/null +++ b/modules/prompt_categories.py @@ -0,0 +1,64 @@ +PROMPT_CATEGORIES = { + "Персонажи": { + "Девушки": [ + "1girl", "2girls", "3girls", "girl", "solo", "multiple_girls", + "little_girl", "loli", "kawaii", "mesugaki", "adorable_girl", + "bishoujo", "gyaru", "sisters", "ojousama", "female", + "mature_female", "female_pervert", "milf", "otoko_no_ko" + ], + "Мальчики": [ + "1boy", "2boys", "3boys", "boy", "little_boy", "shota", + "male", "mature" + ], + "Профессии": [ + "lifeguard", "boxer", "scientist", "athletes", "office lady", + "monk", "crobat", "nun", "nurse", "stewardess", "student", + "waitress", "teacher", "racer", "police", "soldier", + "cheerleader", "actor", "actress", "spy", "agent", "assassin", + "poet", "samurai", "dancing girl", "motorcyclist", "hacker", + "magician", "detective", "doll", "maid", "pilot", "diver", + "bar censor", "missionary", "firefighter", "goalkeeper", "chef", + "astronaut", "cashier", "mailman", "barista", "the hermit", + "makihitsuji", "office_lady", "race_queen", "queen", "doctor", + "knight", "housemaid", "dancer", "ballerina", "gym_leader", + "trap", "priest", "cleric", "wa_maid" + ] + }, + "Жанры": { + "Аниме и манга": [ + "yaoi", "yuri", "harem", "idol", "neon genesis evangelion", + "hatsune miku", "doraemon", "saint seiya", "gojou satoru", + "mazinger", "crayon shin-chan", "slam dunk", "sun wukong" + ], + "Супергерои": [ + "avengers", "captain america", "spider-man", "santa alter" + ], + "Фэнтези": [ + "witch", "miko", "ninja", "vampire", "knight", "magical_girl", + "orc", "druid", "elf", "fairy", "furry", "mermaid", + "kamen rider", "magister", "monster_girl" + ], + "Кемоно": [ + "cat_girl", "dog_girl", "fox_girl", "kitsune", "kyuubi", + "raccoon_girl", "wolf_girl", "bunny_girl", "horse_girl", + "cow_girl", "dragon_girl", "centaur", "slime_musume", + "spider_girl", "dominatrix", "sailor_senshi" + ], + "Футуристика": [ + "mecha", "mecha_musume", "humanoid_robot_", "cyborg" + ], + "Мифология": [ + "angel", "devil", "dark_elf", "imp", "succubus", + "giantess", "minigirl", "monster", "no humans" + ] + }, + "Возраст": { + "Дети": [ + "toddler", "kindergartener", "child", "underage", + "teenager", "teen", "early teen" + ], + "Взрослые": [ + "adult", "elder", "old", "loli", "shota" + ] + } +} \ No newline at end of file diff --git a/modules/prompt_window.py b/modules/prompt_window.py new file mode 100644 index 0000000..2cbd8cf --- /dev/null +++ b/modules/prompt_window.py @@ -0,0 +1,136 @@ +from PyQt6.QtWidgets import (QDialog, QVBoxLayout, QHBoxLayout, QTreeWidget, + QTreeWidgetItem, QPushButton, QLineEdit, QLabel) +from PyQt6.QtCore import Qt, pyqtSignal +from .prompt_categories import PROMPT_CATEGORIES + +class PromptWindow(QDialog): + prompt_selected = pyqtSignal(str) + + def __init__(self, parent=None): + super().__init__(parent) + self.setWindowTitle("Готовые промпты") + self.setModal(False) + self.setup_ui() + self.load_categories() + + def setup_ui(self): + self.setStyleSheet(""" + QDialog { + background-color: #2b2b2b; + min-width: 800px; + min-height: 600px; + } + QTreeWidget { + background-color: #1e1e1e; + color: #ffffff; + border: 1px solid #3b3b3b; + border-radius: 4px; + padding: 8px; + } + QTreeWidget::item { + padding: 4px; + } + QTreeWidget::item:selected { + background-color: #0d6efd; + color: white; + } + QPushButton { + background-color: #0d6efd; + color: white; + border: none; + border-radius: 4px; + padding: 8px 16px; + font-weight: bold; + } + QPushButton:hover { + background-color: #0b5ed7; + } + QPushButton:pressed { + background-color: #0a58ca; + } + QLineEdit { + background-color: #3b3b3b; + color: white; + border: 1px solid #555555; + border-radius: 4px; + padding: 8px; + } + """) + + layout = QVBoxLayout(self) + + # Поиск + search_layout = QHBoxLayout() + search_label = QLabel("Поиск:") + self.search_input = QLineEdit() + self.search_input.textChanged.connect(self.filter_prompts) + search_layout.addWidget(search_label) + search_layout.addWidget(self.search_input) + layout.addLayout(search_layout) + + # Дерево категорий + self.tree = QTreeWidget() + self.tree.setHeaderLabels(["Категории и промпты"]) + self.tree.itemDoubleClicked.connect(self.on_item_double_clicked) + layout.addWidget(self.tree) + + # Кнопки + buttons_layout = QHBoxLayout() + add_button = QPushButton("Добавить выбранное") + add_button.clicked.connect(self.add_selected) + close_button = QPushButton("Закрыть") + close_button.clicked.connect(self.close) + buttons_layout.addWidget(add_button) + buttons_layout.addWidget(close_button) + layout.addLayout(buttons_layout) + + def load_categories(self): + """Загрузка категорий и промптов в дерево""" + for category, subcategories in PROMPT_CATEGORIES.items(): + category_item = QTreeWidgetItem([category]) + self.tree.addTopLevelItem(category_item) + + for subcategory, prompts in subcategories.items(): + subcategory_item = QTreeWidgetItem([subcategory]) + category_item.addChild(subcategory_item) + + for prompt in prompts: + prompt_item = QTreeWidgetItem([prompt]) + subcategory_item.addChild(prompt_item) + + self.tree.expandAll() + + def filter_prompts(self, text): + """Фильтрация промптов по поисковому запросу""" + text = text.lower() + self.tree.clear() + self.load_categories() + + if not text: + return + + def filter_items(item): + if item.childCount() == 0: # Это промпт + return text in item.text(0).lower() + else: # Это категория + has_visible_children = False + for i in range(item.childCount()): + if filter_items(item.child(i)): + has_visible_children = True + if not has_visible_children: + item.parent().removeChild(item) + return has_visible_children + + for i in range(self.tree.topLevelItemCount()): + filter_items(self.tree.topLevelItem(i)) + + def on_item_double_clicked(self, item): + """Обработка двойного клика по элементу""" + if item.childCount() == 0: # Если это промпт + self.prompt_selected.emit(item.text(0)) + + def add_selected(self): + """Добавление выбранного промпта""" + selected_items = self.tree.selectedItems() + if selected_items and selected_items[0].childCount() == 0: + self.prompt_selected.emit(selected_items[0].text(0)) \ No newline at end of file