Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ec5b85573c |
No files matched your search
@@ -17,6 +17,7 @@ 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
|
||||
|
||||
class GenerationThread(QThread):
|
||||
progress_updated = pyqtSignal(float, str)
|
||||
@@ -64,6 +65,7 @@ class MainWindow(QMainWindow):
|
||||
self.api_url = "http://localhost:7860" # URL по умолчанию
|
||||
self.console_window = None
|
||||
self.prompt_window = None
|
||||
self.negative_prompt_window = None
|
||||
self.progress_timer = None
|
||||
self.init_ui()
|
||||
|
||||
@@ -164,29 +166,32 @@ class MainWindow(QMainWindow):
|
||||
settings_layout.addLayout(api_layout)
|
||||
|
||||
# Промпт
|
||||
prompt_label = QLabel("Промпт:")
|
||||
self.prompt_input = QTextEdit()
|
||||
self.prompt_input.setPlaceholderText("Введите описание изображения...")
|
||||
prompt_layout = QVBoxLayout()
|
||||
prompt_header = QHBoxLayout()
|
||||
prompt_header.addWidget(prompt_label)
|
||||
|
||||
# Добавляем кнопку промптов рядом с полем промпта
|
||||
prompt_label = QLabel("Промпт:")
|
||||
self.prompt_input = QTextEdit()
|
||||
self.prompt_input.setMinimumHeight(100)
|
||||
prompt_buttons = QHBoxLayout()
|
||||
self.prompt_button = QPushButton("Готовые промпты")
|
||||
self.prompt_button.clicked.connect(self.toggle_prompt_window)
|
||||
prompt_header.addWidget(self.prompt_button)
|
||||
prompt_header.addStretch()
|
||||
|
||||
self.negative_prompt_button = QPushButton("Негативные промпты")
|
||||
self.negative_prompt_button.clicked.connect(self.toggle_negative_prompt_window)
|
||||
prompt_buttons.addWidget(self.prompt_button)
|
||||
prompt_buttons.addWidget(self.negative_prompt_button)
|
||||
prompt_header.addWidget(prompt_label)
|
||||
prompt_header.addLayout(prompt_buttons)
|
||||
prompt_layout.addLayout(prompt_header)
|
||||
prompt_layout.addWidget(self.prompt_input)
|
||||
settings_layout.addLayout(prompt_layout)
|
||||
|
||||
# Негативный промпт
|
||||
neg_prompt_label = QLabel("Негативный промпт:")
|
||||
self.neg_prompt_input = QTextEdit()
|
||||
self.neg_prompt_input.setPlaceholderText("Введите нежелательные элементы...")
|
||||
settings_layout.addWidget(neg_prompt_label)
|
||||
settings_layout.addWidget(self.neg_prompt_input)
|
||||
negative_prompt_layout = QVBoxLayout()
|
||||
negative_prompt_label = QLabel("Негативный промпт:")
|
||||
self.negative_prompt_input = QTextEdit()
|
||||
self.negative_prompt_input.setMinimumHeight(100)
|
||||
negative_prompt_layout.addWidget(negative_prompt_label)
|
||||
negative_prompt_layout.addWidget(self.negative_prompt_input)
|
||||
settings_layout.addLayout(negative_prompt_layout)
|
||||
|
||||
# Добавляем менеджер моделей
|
||||
self.model_manager = ModelManager(self.api_url)
|
||||
@@ -316,12 +321,28 @@ class MainWindow(QMainWindow):
|
||||
else:
|
||||
self.prompt_window.close()
|
||||
|
||||
def add_prompt(self, prompt):
|
||||
def toggle_negative_prompt_window(self):
|
||||
"""Открыть/закрыть окно с негативными промптами"""
|
||||
if self.negative_prompt_window is None:
|
||||
self.negative_prompt_window = NegativePromptWindow(parent=self)
|
||||
self.negative_prompt_window.prompt_selected.connect(self.add_negative_prompt)
|
||||
self.negative_prompt_window.show()
|
||||
else:
|
||||
self.negative_prompt_window.close()
|
||||
|
||||
def add_prompt(self, text):
|
||||
"""Добавить промпт в поле ввода"""
|
||||
current_text = self.prompt_input.toPlainText()
|
||||
if current_text:
|
||||
current_text += ", "
|
||||
self.prompt_input.setText(current_text + prompt)
|
||||
self.prompt_input.setText(current_text + text)
|
||||
|
||||
def add_negative_prompt(self, text):
|
||||
"""Добавить негативный промпт в поле ввода"""
|
||||
current_text = self.negative_prompt_input.toPlainText()
|
||||
if current_text:
|
||||
current_text += ", "
|
||||
self.negative_prompt_input.setText(current_text + text)
|
||||
|
||||
def start_generation(self):
|
||||
self.generate_button.setEnabled(False)
|
||||
@@ -329,7 +350,7 @@ class MainWindow(QMainWindow):
|
||||
|
||||
params = {
|
||||
"prompt": self.prompt_input.toPlainText(),
|
||||
"negative_prompt": self.neg_prompt_input.toPlainText(),
|
||||
"negative_prompt": self.negative_prompt_input.toPlainText(),
|
||||
"width": self.width_input.value(),
|
||||
"height": self.height_input.value(),
|
||||
"seed": self.seed_input.value(),
|
||||
|
||||
+19
-26
@@ -17,42 +17,36 @@ class ConsoleWindow(QDialog):
|
||||
def setup_ui(self):
|
||||
self.setStyleSheet("""
|
||||
QDialog {
|
||||
background-color: #1e1e1e;
|
||||
min-width: 700px;
|
||||
min-height: 500px;
|
||||
background-color: #2b2b2b;
|
||||
min-width: 600px;
|
||||
min-height: 400px;
|
||||
}
|
||||
QTextEdit {
|
||||
background-color: #252526;
|
||||
color: #d4d4d4;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
font-family: 'JetBrains Mono', 'Consolas', 'Courier New', monospace;
|
||||
font-size: 13px;
|
||||
padding: 12px;
|
||||
selection-background-color: #264f78;
|
||||
background-color: #1e1e1e;
|
||||
color: #ffffff;
|
||||
border: 1px solid #3b3b3b;
|
||||
border-radius: 4px;
|
||||
font-family: 'Consolas', 'Courier New', monospace;
|
||||
font-size: 12px;
|
||||
padding: 8px;
|
||||
}
|
||||
QPushButton {
|
||||
background-color: #2d2d2d;
|
||||
color: #d4d4d4;
|
||||
border: 1px solid #3e3e3e;
|
||||
border-radius: 6px;
|
||||
background-color: #0d6efd;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
padding: 8px 16px;
|
||||
font-weight: 500;
|
||||
min-width: 100px;
|
||||
margin: 4px;
|
||||
font-weight: bold;
|
||||
}
|
||||
QPushButton:hover {
|
||||
background-color: #3e3e3e;
|
||||
border-color: #565656;
|
||||
background-color: #0b5ed7;
|
||||
}
|
||||
QPushButton:pressed {
|
||||
background-color: #565656;
|
||||
background-color: #0a58ca;
|
||||
}
|
||||
""")
|
||||
|
||||
layout = QVBoxLayout(self)
|
||||
layout.setContentsMargins(16, 16, 16, 16)
|
||||
layout.setSpacing(12)
|
||||
|
||||
# Область для логов
|
||||
self.console_output = QTextEdit()
|
||||
@@ -61,12 +55,11 @@ class ConsoleWindow(QDialog):
|
||||
|
||||
# Кнопки управления
|
||||
buttons_layout = QHBoxLayout()
|
||||
buttons_layout.setSpacing(8)
|
||||
|
||||
copy_button = QPushButton("📋 Копировать")
|
||||
copy_button = QPushButton("Копировать всё")
|
||||
copy_button.clicked.connect(self.copy_all)
|
||||
|
||||
clear_button = QPushButton("🗑️ Очистить")
|
||||
clear_button = QPushButton("Очистить")
|
||||
clear_button.clicked.connect(self.clear_console)
|
||||
|
||||
buttons_layout.addWidget(copy_button)
|
||||
|
||||
@@ -13,65 +13,8 @@ class ModelManager(QWidget):
|
||||
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("Модель:")
|
||||
@@ -79,13 +22,11 @@ class ModelManager(QWidget):
|
||||
|
||||
# Выпадающий список моделей
|
||||
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)
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
NEGATIVE_PROMPT_CATEGORIES = {
|
||||
"Общие проблемы": {
|
||||
"Качество": [
|
||||
"Низкое качество",
|
||||
"Обычное качество",
|
||||
"Худшее качество",
|
||||
"Низкое разрешение",
|
||||
"Размытое",
|
||||
"Не в фокусе"
|
||||
],
|
||||
"Технические артефакты": [
|
||||
"Логотип",
|
||||
"Текст",
|
||||
"Подпись",
|
||||
"Водяной знак",
|
||||
"Обрезанное",
|
||||
"Монохромное",
|
||||
"Оттенки серого"
|
||||
],
|
||||
"Контент": [
|
||||
"Нецензурный контент",
|
||||
"NSFW",
|
||||
"Удалить взрослых",
|
||||
"Удалить молодых"
|
||||
]
|
||||
},
|
||||
"Анатомия": {
|
||||
"Общие проблемы": [
|
||||
"Неправильная анатомия",
|
||||
"Плохое тело",
|
||||
"Длинное тело",
|
||||
"Длинная шея",
|
||||
"Неправильные пропорции",
|
||||
"Деформированный",
|
||||
"Мутировавший",
|
||||
"Мутация",
|
||||
"Уродливый",
|
||||
"Испорченный"
|
||||
],
|
||||
"Лицо": [
|
||||
"Плохо нарисованное лицо",
|
||||
"Пятна на коже",
|
||||
"Веснушки",
|
||||
"Прыщи",
|
||||
"Косоглазый"
|
||||
],
|
||||
"Конечности": [
|
||||
"Отсутствующая конечность",
|
||||
"Деформированные конечности",
|
||||
"Плавающие конечности",
|
||||
"Отсоединенные конечности",
|
||||
"Дополнительная конечность",
|
||||
"Дополнительные руки",
|
||||
"Мутировавшие руки",
|
||||
"Плохо нарисованные руки",
|
||||
"Деформированные руки",
|
||||
"Мутировавшие руки и пальцы",
|
||||
"Плохие руки",
|
||||
"Отсутствующие пальцы",
|
||||
"Сросшиеся пальцы",
|
||||
"Слишком много пальцев",
|
||||
"Дополнительные ноги",
|
||||
"Плохие ноги"
|
||||
]
|
||||
},
|
||||
"Дополнительные модели": {
|
||||
"Негативные модели": [
|
||||
"AS-YoungV2-neg",
|
||||
"BadDream",
|
||||
"badhandv4",
|
||||
"BadNegAnatomyV1-neg",
|
||||
"EasyNegative",
|
||||
"FastNegativeV2"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
# Словарь для перевода русских названий в английские
|
||||
NEGATIVE_PROMPT_TRANSLATIONS = {
|
||||
"Низкое качество": "low quality",
|
||||
"Обычное качество": "normal quality",
|
||||
"Худшее качество": "worstquality",
|
||||
"Низкое разрешение": "lowres",
|
||||
"Размытое": "blurry",
|
||||
"Не в фокусе": "out of focus",
|
||||
"Логотип": "logo",
|
||||
"Текст": "text",
|
||||
"Подпись": "signature",
|
||||
"Водяной знак": "watermark",
|
||||
"Обрезанное": "cropped",
|
||||
"Монохромное": "monochrome",
|
||||
"Оттенки серого": "grayscale",
|
||||
"Нецензурный контент": "NSFW content",
|
||||
"NSFW": "NSFW",
|
||||
"Удалить взрослых": "(AS-YoungV2-Neg:1.3)",
|
||||
"Удалить молодых": "(AS-Adult-Neg:1.3)",
|
||||
"Неправильная анатомия": "bad anatomy",
|
||||
"Плохое тело": "bad body",
|
||||
"Длинное тело": "long body",
|
||||
"Длинная шея": "long neck",
|
||||
"Неправильные пропорции": "bad proportions",
|
||||
"Деформированный": "deformed",
|
||||
"Мутировавший": "mutated",
|
||||
"Мутация": "mutation",
|
||||
"Уродливый": "ugly",
|
||||
"Испорченный": "disfigured",
|
||||
"Плохо нарисованное лицо": "poorly drawn face",
|
||||
"Пятна на коже": "skin blemishes",
|
||||
"Веснушки": "skin spots",
|
||||
"Прыщи": "acnes",
|
||||
"Косоглазый": "cross-eyed",
|
||||
"Отсутствующая конечность": "missing limb",
|
||||
"Деформированные конечности": "malformed limbs",
|
||||
"Плавающие конечности": "floating limbs",
|
||||
"Отсоединенные конечности": "disconnected limbs",
|
||||
"Дополнительная конечность": "extra limb",
|
||||
"Дополнительные руки": "extra arms",
|
||||
"Мутировавшие руки": "mutated hands",
|
||||
"Плохо нарисованные руки": "poorly drawn hands",
|
||||
"Деформированные руки": "malformed hands",
|
||||
"Мутировавшие руки и пальцы": "mutated hands and fingers",
|
||||
"Плохие руки": "bad hands",
|
||||
"Отсутствующие пальцы": "missing fingers",
|
||||
"Сросшиеся пальцы": "fused fingers",
|
||||
"Слишком много пальцев": "too many fingers",
|
||||
"Дополнительные ноги": "extra legs",
|
||||
"Плохие ноги": "bad feet",
|
||||
"AS-YoungV2-neg": "AS-YoungV2-neg",
|
||||
"BadDream": "BadDream",
|
||||
"badhandv4": "badhandv4",
|
||||
"BadNegAnatomyV1-neg": "BadNegAnatomyV1-neg",
|
||||
"EasyNegative": "EasyNegative",
|
||||
"FastNegativeV2": "FastNegativeV2"
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
from PyQt6.QtWidgets import (QDialog, QVBoxLayout, QHBoxLayout, QPushButton,
|
||||
QLineEdit, QLabel, QScrollArea, QWidget, QCheckBox, QFrame)
|
||||
from PyQt6.QtCore import Qt, pyqtSignal
|
||||
from .negative_prompt_categories import NEGATIVE_PROMPT_CATEGORIES, NEGATIVE_PROMPT_TRANSLATIONS
|
||||
|
||||
class NegativePromptWindow(QDialog):
|
||||
prompt_selected = pyqtSignal(str)
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.setWindowTitle("Негативные промпты")
|
||||
self.setModal(False)
|
||||
self.selected_prompts = set()
|
||||
self.setup_ui()
|
||||
self.load_categories()
|
||||
|
||||
def setup_ui(self):
|
||||
self.setStyleSheet("""
|
||||
QDialog {
|
||||
background-color: #2b2b2b;
|
||||
min-width: 1500px;
|
||||
min-height: 700px;
|
||||
}
|
||||
QScrollArea {
|
||||
background-color: #1e1e1e;
|
||||
border: 1px solid #3b3b3b;
|
||||
border-radius: 4px;
|
||||
padding: 8px;
|
||||
}
|
||||
QScrollArea > QWidget > QWidget {
|
||||
background-color: #1e1e1e;
|
||||
}
|
||||
QLabel {
|
||||
color: #ffffff;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
padding: 8px;
|
||||
background-color: #3b3b3b;
|
||||
border-radius: 4px;
|
||||
}
|
||||
QCheckBox {
|
||||
color: #ffffff;
|
||||
font-size: 14px;
|
||||
padding: 4px;
|
||||
spacing: 8px;
|
||||
}
|
||||
QCheckBox::indicator {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
QCheckBox::indicator:unchecked {
|
||||
border: 2px solid #555555;
|
||||
background-color: #3b3b3b;
|
||||
border-radius: 3px;
|
||||
}
|
||||
QCheckBox::indicator:checked {
|
||||
border: 2px solid #dc3545;
|
||||
background-color: #dc3545;
|
||||
border-radius: 3px;
|
||||
}
|
||||
QCheckBox::indicator:hover {
|
||||
border-color: #bb2d3b;
|
||||
}
|
||||
QPushButton {
|
||||
background-color: #dc3545;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
padding: 8px 16px;
|
||||
font-weight: bold;
|
||||
min-width: 120px;
|
||||
}
|
||||
QPushButton:hover {
|
||||
background-color: #bb2d3b;
|
||||
}
|
||||
QPushButton:pressed {
|
||||
background-color: #a52834;
|
||||
}
|
||||
QLineEdit {
|
||||
background-color: #3b3b3b;
|
||||
color: white;
|
||||
border: 1px solid #555555;
|
||||
border-radius: 4px;
|
||||
padding: 8px;
|
||||
font-size: 14px;
|
||||
min-height: 24px;
|
||||
}
|
||||
QFrame {
|
||||
background-color: #1e1e1e;
|
||||
border: 1px solid #3b3b3b;
|
||||
border-radius: 4px;
|
||||
}
|
||||
""")
|
||||
|
||||
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)
|
||||
|
||||
# Горизонтальная прокрутка для категорий
|
||||
categories_scroll = QScrollArea()
|
||||
categories_scroll.setWidgetResizable(True)
|
||||
categories_scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOn)
|
||||
categories_scroll.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
|
||||
|
||||
categories_widget = QWidget()
|
||||
self.categories_layout = QHBoxLayout(categories_widget)
|
||||
self.categories_layout.setSpacing(10)
|
||||
categories_scroll.setWidget(categories_widget)
|
||||
|
||||
layout.addWidget(categories_scroll)
|
||||
|
||||
# Кнопки
|
||||
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 NEGATIVE_PROMPT_CATEGORIES.items():
|
||||
# Создаем фрейм для категории
|
||||
category_frame = QFrame()
|
||||
category_layout = QVBoxLayout(category_frame)
|
||||
category_layout.setSpacing(5)
|
||||
|
||||
# Добавляем заголовок категории
|
||||
category_label = QLabel(category)
|
||||
category_layout.addWidget(category_label)
|
||||
|
||||
# Создаем скролл для подкатегорий
|
||||
subcategories_scroll = QScrollArea()
|
||||
subcategories_scroll.setWidgetResizable(True)
|
||||
subcategories_widget = QWidget()
|
||||
subcategories_layout = QVBoxLayout(subcategories_widget)
|
||||
|
||||
for subcategory, prompts in subcategories.items():
|
||||
# Добавляем заголовок подкатегории
|
||||
subcategory_label = QLabel(subcategory)
|
||||
subcategories_layout.addWidget(subcategory_label)
|
||||
|
||||
# Добавляем чекбоксы для промптов
|
||||
for prompt in prompts:
|
||||
checkbox = QCheckBox(prompt)
|
||||
checkbox.stateChanged.connect(lambda state, p=prompt: self.on_checkbox_changed(state, p))
|
||||
subcategories_layout.addWidget(checkbox)
|
||||
|
||||
subcategories_scroll.setWidget(subcategories_widget)
|
||||
category_layout.addWidget(subcategories_scroll)
|
||||
|
||||
# Добавляем категорию в горизонтальный layout
|
||||
self.categories_layout.addWidget(category_frame)
|
||||
|
||||
def on_checkbox_changed(self, state, prompt):
|
||||
"""Обработка изменения состояния чекбокса"""
|
||||
if state == Qt.CheckState.Checked.value:
|
||||
self.selected_prompts.add(prompt)
|
||||
else:
|
||||
self.selected_prompts.discard(prompt)
|
||||
|
||||
def filter_prompts(self, text):
|
||||
"""Фильтрация промптов по поисковому запросу"""
|
||||
text = text.lower()
|
||||
for i in range(self.categories_layout.count()):
|
||||
category_frame = self.categories_layout.itemAt(i).widget()
|
||||
for j in range(category_frame.layout().count()):
|
||||
widget = category_frame.layout().itemAt(j).widget()
|
||||
if isinstance(widget, QScrollArea):
|
||||
scroll_widget = widget.widget()
|
||||
for k in range(scroll_widget.layout().count()):
|
||||
sub_widget = scroll_widget.layout().itemAt(k).widget()
|
||||
if isinstance(sub_widget, QCheckBox):
|
||||
sub_widget.setVisible(text in sub_widget.text().lower())
|
||||
elif isinstance(sub_widget, QLabel):
|
||||
# Показываем/скрываем заголовок подкатегории в зависимости от видимости его промптов
|
||||
has_visible_prompts = False
|
||||
for l in range(k + 1, scroll_widget.layout().count()):
|
||||
next_widget = scroll_widget.layout().itemAt(l).widget()
|
||||
if isinstance(next_widget, QCheckBox) and next_widget.isVisible():
|
||||
has_visible_prompts = True
|
||||
break
|
||||
sub_widget.setVisible(has_visible_prompts)
|
||||
|
||||
def add_selected(self):
|
||||
"""Добавление выбранных промптов"""
|
||||
if self.selected_prompts:
|
||||
# Преобразуем русские названия в английские
|
||||
translated_prompts = [NEGATIVE_PROMPT_TRANSLATIONS.get(prompt, prompt) for prompt in self.selected_prompts]
|
||||
prompts_text = ", ".join(sorted(translated_prompts))
|
||||
self.prompt_selected.emit(prompts_text)
|
||||
+44
-66
@@ -18,105 +18,87 @@ class PromptWindow(QDialog):
|
||||
def setup_ui(self):
|
||||
self.setStyleSheet("""
|
||||
QDialog {
|
||||
background-color: #1e1e1e;
|
||||
min-width: 1200px;
|
||||
min-height: 800px;
|
||||
background-color: #2b2b2b;
|
||||
min-width: 1500px;
|
||||
min-height: 700px;
|
||||
}
|
||||
QScrollArea {
|
||||
background-color: #252526;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
background-color: #1e1e1e;
|
||||
border: 1px solid #3b3b3b;
|
||||
border-radius: 4px;
|
||||
padding: 8px;
|
||||
}
|
||||
QScrollArea > QWidget > QWidget {
|
||||
background-color: #252526;
|
||||
background-color: #1e1e1e;
|
||||
}
|
||||
QLabel {
|
||||
color: #d4d4d4;
|
||||
color: #ffffff;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
padding: 12px;
|
||||
background-color: #2d2d2d;
|
||||
border-radius: 6px;
|
||||
margin-bottom: 8px;
|
||||
font-weight: bold;
|
||||
padding: 8px;
|
||||
background-color: #3b3b3b;
|
||||
border-radius: 4px;
|
||||
}
|
||||
QCheckBox {
|
||||
color: #d4d4d4;
|
||||
font-size: 13px;
|
||||
padding: 6px;
|
||||
color: #ffffff;
|
||||
font-size: 14px;
|
||||
padding: 4px;
|
||||
spacing: 8px;
|
||||
}
|
||||
QCheckBox:hover {
|
||||
background-color: #2d2d2d;
|
||||
border-radius: 4px;
|
||||
}
|
||||
QCheckBox::indicator {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
QCheckBox::indicator:unchecked {
|
||||
border: 2px solid #565656;
|
||||
background-color: #252526;
|
||||
border: 2px solid #555555;
|
||||
background-color: #3b3b3b;
|
||||
border-radius: 3px;
|
||||
}
|
||||
QCheckBox::indicator:checked {
|
||||
border: 2px solid #007acc;
|
||||
background-color: #007acc;
|
||||
border: 2px solid #0d6efd;
|
||||
background-color: #0d6efd;
|
||||
border-radius: 3px;
|
||||
}
|
||||
QCheckBox::indicator:hover {
|
||||
border-color: #007acc;
|
||||
border-color: #0b5ed7;
|
||||
}
|
||||
QPushButton {
|
||||
background-color: #2d2d2d;
|
||||
color: #d4d4d4;
|
||||
border: 1px solid #3e3e3e;
|
||||
border-radius: 6px;
|
||||
background-color: #0d6efd;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
padding: 8px 16px;
|
||||
font-weight: 500;
|
||||
font-weight: bold;
|
||||
min-width: 120px;
|
||||
font-size: 13px;
|
||||
}
|
||||
QPushButton:hover {
|
||||
background-color: #3e3e3e;
|
||||
border-color: #565656;
|
||||
background-color: #0b5ed7;
|
||||
}
|
||||
QPushButton:pressed {
|
||||
background-color: #565656;
|
||||
background-color: #0a58ca;
|
||||
}
|
||||
QLineEdit {
|
||||
background-color: #252526;
|
||||
color: #d4d4d4;
|
||||
border: 1px solid #3e3e3e;
|
||||
border-radius: 6px;
|
||||
padding: 8px 12px;
|
||||
font-size: 13px;
|
||||
min-height: 32px;
|
||||
}
|
||||
QLineEdit:focus {
|
||||
border-color: #007acc;
|
||||
background-color: #3b3b3b;
|
||||
color: white;
|
||||
border: 1px solid #555555;
|
||||
border-radius: 4px;
|
||||
padding: 8px;
|
||||
font-size: 14px;
|
||||
min-height: 24px;
|
||||
}
|
||||
QFrame {
|
||||
background-color: #252526;
|
||||
border: 1px solid #3e3e3e;
|
||||
border-radius: 8px;
|
||||
padding: 12px;
|
||||
margin: 4px;
|
||||
}
|
||||
QFrame:hover {
|
||||
border-color: #565656;
|
||||
background-color: #1e1e1e;
|
||||
border: 1px solid #3b3b3b;
|
||||
border-radius: 4px;
|
||||
}
|
||||
""")
|
||||
|
||||
layout = QVBoxLayout(self)
|
||||
layout.setContentsMargins(16, 16, 16, 16)
|
||||
layout.setSpacing(12)
|
||||
|
||||
# Поиск
|
||||
search_layout = QHBoxLayout()
|
||||
search_layout.setSpacing(8)
|
||||
search_label = QLabel("🔍 Поиск:")
|
||||
search_label.setStyleSheet("background: transparent; padding: 0;")
|
||||
search_label = QLabel("Поиск:")
|
||||
self.search_input = QLineEdit()
|
||||
self.search_input.setPlaceholderText("Введите текст для поиска...")
|
||||
self.search_input.textChanged.connect(self.filter_prompts)
|
||||
search_layout.addWidget(search_label)
|
||||
search_layout.addWidget(self.search_input)
|
||||
@@ -127,26 +109,22 @@ class PromptWindow(QDialog):
|
||||
categories_scroll.setWidgetResizable(True)
|
||||
categories_scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOn)
|
||||
categories_scroll.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
|
||||
categories_scroll.setMinimumHeight(600)
|
||||
|
||||
categories_widget = QWidget()
|
||||
self.categories_layout = QHBoxLayout(categories_widget)
|
||||
self.categories_layout.setSpacing(12)
|
||||
self.categories_layout.setContentsMargins(12, 12, 12, 12)
|
||||
self.categories_layout.setSpacing(10)
|
||||
categories_scroll.setWidget(categories_widget)
|
||||
|
||||
layout.addWidget(categories_scroll)
|
||||
|
||||
# Кнопки
|
||||
buttons_layout = QHBoxLayout()
|
||||
buttons_layout.setSpacing(8)
|
||||
add_button = QPushButton("✨ Добавить выбранные")
|
||||
add_button = QPushButton("Добавить выбранные")
|
||||
add_button.clicked.connect(self.add_selected)
|
||||
close_button = QPushButton("❌ Закрыть")
|
||||
close_button = QPushButton("Закрыть")
|
||||
close_button.clicked.connect(self.close)
|
||||
buttons_layout.addWidget(add_button)
|
||||
buttons_layout.addWidget(close_button)
|
||||
buttons_layout.addStretch()
|
||||
layout.addLayout(buttons_layout)
|
||||
|
||||
def load_categories(self):
|
||||
|
||||
@@ -13,50 +13,8 @@ class SamplerManager(QWidget):
|
||||
self.load_samplers()
|
||||
|
||||
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: 180px;
|
||||
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;
|
||||
}
|
||||
""")
|
||||
|
||||
layout = QHBoxLayout(self)
|
||||
layout.setContentsMargins(0, 0, 0, 0)
|
||||
layout.setSpacing(8)
|
||||
|
||||
# Метка
|
||||
label = QLabel("Сэмплер:")
|
||||
@@ -64,7 +22,6 @@ class SamplerManager(QWidget):
|
||||
|
||||
# Выпадающий список сэмплеров
|
||||
self.sampler_combo = QComboBox()
|
||||
self.sampler_combo.setFixedHeight(32)
|
||||
self.sampler_combo.currentTextChanged.connect(self.on_sampler_changed)
|
||||
layout.addWidget(self.sampler_combo)
|
||||
|
||||
|
||||
Reference in new issue
Block a user