Author SHA1 Message Date
kromskii2 02c7b9483b Улучшен интерфейс менеджера пресетов размеров: добавлен фрейм для кнопок, изменены стили кнопок и заголовка, улучшено разделение пресетов на две группы. Изменены названия пресетов для упрощения. Добавлен метод создания кнопок с улучшенным дизайном. 2025-03-14 20:20:55 +07:00
kromskii2 8e6e54c802 Добавлены новые бинарные файлы для кэширования модулей: negative_prompt_categories, negative_prompt_window, prompt_categories, prompt_translations, prompt_window, size_preset_manager и size_presets. 2025-03-14 20:05:25 +07:00
kromskii2 603f6827b6 Добавлены пресеты размеров изображения с красивыми кнопками 2025-03-14 20:03:37 +07:00
kromskii2 41999b31c1 Добавлена кнопка копирования изображения в буфер обмена 2025-03-14 19:59:11 +07:00
kromskii2 6e2defe3b6 Добавлены переводы промптов и изменен размер окна негативных промптов 2025-03-14 19:56:00 +07:00
kromskii2 ec5b85573c Добавлено окно негативных промптов с категориями и автоматическим переводом 2025-03-14 19:49:29 +07:00
14 changed files with 832 additions and 20 deletions

No files matched your search

+77 -19
View File
@@ -17,6 +17,8 @@ from modules.console_window import ConsoleWindow
from modules.model_manager import ModelManager from modules.model_manager import ModelManager
from modules.sampler_manager import SamplerManager from modules.sampler_manager import SamplerManager
from modules.prompt_window import PromptWindow from modules.prompt_window import PromptWindow
from modules.negative_prompt_window import NegativePromptWindow
from modules.size_preset_manager import SizePresetManager
class GenerationThread(QThread): class GenerationThread(QThread):
progress_updated = pyqtSignal(float, str) progress_updated = pyqtSignal(float, str)
@@ -64,6 +66,7 @@ class MainWindow(QMainWindow):
self.api_url = "http://localhost:7860" # URL по умолчанию self.api_url = "http://localhost:7860" # URL по умолчанию
self.console_window = None self.console_window = None
self.prompt_window = None self.prompt_window = None
self.negative_prompt_window = None
self.progress_timer = None self.progress_timer = None
self.init_ui() self.init_ui()
@@ -164,29 +167,32 @@ class MainWindow(QMainWindow):
settings_layout.addLayout(api_layout) settings_layout.addLayout(api_layout)
# Промпт # Промпт
prompt_label = QLabel("Промпт:")
self.prompt_input = QTextEdit()
self.prompt_input.setPlaceholderText("Введите описание изображения...")
prompt_layout = QVBoxLayout() prompt_layout = QVBoxLayout()
prompt_header = QHBoxLayout() 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 = QPushButton("Готовые промпты")
self.prompt_button.clicked.connect(self.toggle_prompt_window) self.prompt_button.clicked.connect(self.toggle_prompt_window)
prompt_header.addWidget(self.prompt_button) self.negative_prompt_button = QPushButton("Негативные промпты")
prompt_header.addStretch() 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.addLayout(prompt_header)
prompt_layout.addWidget(self.prompt_input) prompt_layout.addWidget(self.prompt_input)
settings_layout.addLayout(prompt_layout) settings_layout.addLayout(prompt_layout)
# Негативный промпт # Негативный промпт
neg_prompt_label = QLabel("Негативный промпт:") negative_prompt_layout = QVBoxLayout()
self.neg_prompt_input = QTextEdit() negative_prompt_label = QLabel("Негативный промпт:")
self.neg_prompt_input.setPlaceholderText("Введите нежелательные элементы...") self.negative_prompt_input = QTextEdit()
settings_layout.addWidget(neg_prompt_label) self.negative_prompt_input.setMinimumHeight(100)
settings_layout.addWidget(self.neg_prompt_input) 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) self.model_manager = ModelManager(self.api_url)
@@ -197,6 +203,11 @@ class MainWindow(QMainWindow):
self.sampler_manager = SamplerManager(self.api_url) self.sampler_manager = SamplerManager(self.api_url)
settings_layout.addWidget(self.sampler_manager) settings_layout.addWidget(self.sampler_manager)
# Добавляем менеджер пресетов размеров
self.size_preset_manager = SizePresetManager()
self.size_preset_manager.size_changed.connect(self.on_size_preset_changed)
settings_layout.addWidget(self.size_preset_manager)
# Параметры генерации # Параметры генерации
params_layout = QVBoxLayout() params_layout = QVBoxLayout()
@@ -316,12 +327,28 @@ class MainWindow(QMainWindow):
else: else:
self.prompt_window.close() 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() current_text = self.prompt_input.toPlainText()
if current_text: if current_text:
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): def start_generation(self):
self.generate_button.setEnabled(False) self.generate_button.setEnabled(False)
@@ -329,7 +356,7 @@ class MainWindow(QMainWindow):
params = { params = {
"prompt": self.prompt_input.toPlainText(), "prompt": self.prompt_input.toPlainText(),
"negative_prompt": self.neg_prompt_input.toPlainText(), "negative_prompt": self.negative_prompt_input.toPlainText(),
"width": self.width_input.value(), "width": self.width_input.value(),
"height": self.height_input.value(), "height": self.height_input.value(),
"seed": self.seed_input.value(), "seed": self.seed_input.value(),
@@ -426,11 +453,20 @@ class MainWindow(QMainWindow):
save_button = QPushButton("Сохранить") save_button = QPushButton("Сохранить")
save_button.clicked.connect(lambda checked, img=img: self.save_image(img)) save_button.clicked.connect(lambda checked, img=img: self.save_image(img))
# Создаем контейнер для изображения и кнопки # Создаем кнопку копирования в буфер обмена
copy_button = QPushButton("Копировать")
copy_button.clicked.connect(lambda checked, img=img: self.copy_to_clipboard(img))
# Создаем контейнер для изображения и кнопок
container = QWidget() container = QWidget()
container_layout = QVBoxLayout(container) container_layout = QVBoxLayout(container)
container_layout.addWidget(img_label) container_layout.addWidget(img_label)
container_layout.addWidget(save_button)
# Создаем горизонтальный layout для кнопок
buttons_layout = QHBoxLayout()
buttons_layout.addWidget(save_button)
buttons_layout.addWidget(copy_button)
container_layout.addLayout(buttons_layout)
self.results_content_layout.addWidget(container) self.results_content_layout.addWidget(container)
self.log_to_console("Изображение успешно добавлено в интерфейс") self.log_to_console("Изображение успешно добавлено в интерфейс")
@@ -450,6 +486,22 @@ class MainWindow(QMainWindow):
if file_path: if file_path:
img.save(file_path) img.save(file_path)
def copy_to_clipboard(self, img):
"""Копирование изображения в буфер обмена"""
# Конвертируем изображение в QPixmap
buffer = BytesIO()
img.save(buffer, format='PNG')
buffer.seek(0)
pixmap = QPixmap()
pixmap.loadFromData(buffer.getvalue())
# Копируем в буфер обмена
clipboard = QApplication.clipboard()
clipboard.setPixmap(pixmap)
# Показываем уведомление
self.log_to_console("Изображение скопировано в буфер обмена")
def update_api_url(self): def update_api_url(self):
"""Обновление URL API во всех компонентах""" """Обновление URL API во всех компонентах"""
new_url = self.api_url_input.text() new_url = self.api_url_input.text()
@@ -457,6 +509,12 @@ class MainWindow(QMainWindow):
self.sampler_manager.update_api_url(new_url) self.sampler_manager.update_api_url(new_url)
self.log_to_console(f"API URL обновлен: {new_url}") self.log_to_console(f"API URL обновлен: {new_url}")
def on_size_preset_changed(self, width, height):
"""Обработчик изменения размера через пресет"""
self.width_input.setValue(width)
self.height_input.setValue(height)
self.log_to_console(f"Размер изменен на: {width}x{height}")
if __name__ == '__main__': if __name__ == '__main__':
app = QApplication(sys.argv) app = QApplication(sys.argv)
window = MainWindow() window = MainWindow()
Binary file not shown.
Binary file not shown.
+134
View File
@@ -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"
}
+200
View File
@@ -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: 1700px;
min-height: 800px;
}
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)
+316
View File
@@ -0,0 +1,316 @@
PROMPT_TRANSLATIONS = {
# Персонажи
"Девушка": "girl",
"Парень": "boy",
"Мужчина": "man",
"Женщина": "woman",
"Ребенок": "child",
"Малыш": "baby",
"Пожилой человек": "elderly person",
"Старик": "old man",
"Старушка": "old woman",
# Профессии
"Художник": "artist",
"Музыкант": "musician",
"Писатель": "writer",
"Учитель": "teacher",
"Врач": "doctor",
"Инженер": "engineer",
"Программист": "programmer",
"Повар": "chef",
"Полицейский": "police officer",
"Пожарный": "firefighter",
# Животные
"Кошка": "cat",
"Собака": "dog",
"Птица": "bird",
"Рыба": "fish",
"Лошадь": "horse",
"Корова": "cow",
"Овца": "sheep",
"Коза": "goat",
"Кролик": "rabbit",
"Хомяк": "hamster",
# Природа
"Гора": "mountain",
"Море": "sea",
"Океан": "ocean",
"Река": "river",
"Лес": "forest",
"Поле": "field",
"Цветок": "flower",
"Дерево": "tree",
"Трава": "grass",
"Песок": "sand",
# Погода
"Солнце": "sun",
"Дождь": "rain",
"Снег": "snow",
"Ветер": "wind",
"Туман": "fog",
"Облако": "cloud",
"Гроза": "thunderstorm",
"Радуга": "rainbow",
"Мороз": "frost",
"Иней": "hoarfrost",
# Время суток
"Утро": "morning",
"День": "day",
"Вечер": "evening",
"Ночь": "night",
"Рассвет": "dawn",
"Закат": "sunset",
"Полдень": "noon",
"Полночь": "midnight",
# Сезоны
"Весна": "spring",
"Лето": "summer",
"Осень": "autumn",
"Зима": "winter",
# Эмоции
"Счастье": "happiness",
"Грусть": "sadness",
"Гнев": "anger",
"Страх": "fear",
"Удивление": "surprise",
"Отвращение": "disgust",
"Любовь": "love",
"Ненависть": "hate",
"Спокойствие": "calmness",
"Волнение": "excitement",
# Действия
"Бег": "running",
"Ходьба": "walking",
"Прыжок": "jumping",
"Плавание": "swimming",
"Танцы": "dancing",
"Пение": "singing",
"Игра": "playing",
"Работа": "working",
"Отдых": "resting",
"Сон": "sleeping",
# Одежда
"Платье": "dress",
"Рубашка": "shirt",
"Брюки": "pants",
"Юбка": "skirt",
"Куртка": "jacket",
"Пальто": "coat",
"Шапка": "hat",
"Обувь": "shoes",
"Перчатки": "gloves",
"Шарф": "scarf",
# Цвета
"Красный": "red",
"Синий": "blue",
"Зеленый": "green",
"Желтый": "yellow",
"Белый": "white",
"Черный": "black",
"Серый": "gray",
"Коричневый": "brown",
"Оранжевый": "orange",
"Фиолетовый": "purple",
# Материалы
"Дерево": "wood",
"Металл": "metal",
"Стекло": "glass",
"Пластик": "plastic",
"Ткань": "fabric",
"Бумага": "paper",
"Камень": "stone",
"Керамика": "ceramics",
"Кожа": "leather",
"Резина": "rubber",
# Технологии
"Компьютер": "computer",
"Телефон": "phone",
"Планшет": "tablet",
"Робот": "robot",
"Дрон": "drone",
"Смартфон": "smartphone",
"Ноутбук": "laptop",
"Принтер": "printer",
"Камера": "camera",
"Наушники": "headphones",
# Транспорт
"Машина": "car",
"Велосипед": "bicycle",
"Мотоцикл": "motorcycle",
"Поезд": "train",
"Самолет": "airplane",
"Корабль": "ship",
"Автобус": "bus",
"Трамвай": "tram",
"Метро": "subway",
"Вертолет": "helicopter",
# Еда
"Фрукты": "fruits",
"Овощи": "vegetables",
"Мясо": "meat",
"Рыба": "fish",
"Хлеб": "bread",
"Молоко": "milk",
"Сок": "juice",
"Кофе": "coffee",
"Чай": "tea",
"Сладости": "sweets",
# Дом
"Дом": "house",
"Квартира": "apartment",
"Комната": "room",
"Кухня": "kitchen",
"Спальня": "bedroom",
"Ванная": "bathroom",
"Гостиная": "living room",
"Балкон": "balcony",
"Подвал": "basement",
"Чердак": "attic",
# Музыка
"Гитара": "guitar",
"Пианино": "piano",
"Скрипка": "violin",
"Барабаны": "drums",
"Флейта": "flute",
"Саксофон": "saxophone",
"Труба": "trumpet",
"Бас": "bass",
"Синтезатор": "synthesizer",
"Микрофон": "microphone",
# Спорт
"Футбол": "football",
"Баскетбол": "basketball",
"Волейбол": "volleyball",
"Теннис": "tennis",
"Хоккей": "hockey",
"Бег": "running",
"Плавание": "swimming",
"Бокс": "boxing",
"Йога": "yoga",
"Гимнастика": "gymnastics",
# Искусство
"Картина": "painting",
"Рисунок": "drawing",
"Скульптура": "sculpture",
"Фотография": "photography",
"Кино": "movie",
"Театр": "theater",
"Музыка": "music",
"Танец": "dance",
"Поэзия": "poetry",
"Литература": "literature",
# Наука
"Физика": "physics",
"Химия": "chemistry",
"Биология": "biology",
"Математика": "mathematics",
"Астрономия": "astronomy",
"Геология": "geology",
"Экология": "ecology",
"Психология": "psychology",
"История": "history",
"География": "geography",
# Время
"Секунда": "second",
"Минута": "minute",
"Час": "hour",
"День": "day",
"Неделя": "week",
"Месяц": "month",
"Год": "year",
"Век": "century",
"Эпоха": "era",
"Период": "period",
# География
"Страна": "country",
"Город": "city",
"Деревня": "village",
"Река": "river",
"Озеро": "lake",
"Море": "sea",
"Океан": "ocean",
"Гора": "mountain",
"Пустыня": "desert",
"Джунгли": "jungle",
# Космос
"Солнце": "sun",
"Луна": "moon",
"Звезда": "star",
"Планета": "planet",
"Галактика": "galaxy",
"Вселенная": "universe",
"Астероид": "asteroid",
"Комета": "comet",
"Спутник": "satellite",
"Космический корабль": "spaceship",
# Фэнтези
"Дракон": "dragon",
"Единорог": "unicorn",
"Фея": "fairy",
"Волшебник": "wizard",
"Ведьма": "witch",
"Гоблин": "goblin",
"Эльф": "elf",
"Гном": "dwarf",
"Орк": "orc",
"Тролль": "troll",
# Мифология
"Бог": "god",
"Богиня": "goddess",
"Герой": "hero",
"Миф": "myth",
"Легенда": "legend",
"Демон": "demon",
"Ангел": "angel",
"Призрак": "ghost",
"Вампир": "vampire",
"Оборотень": "werewolf",
# Стили искусства
"Реализм": "realism",
"Импрессионизм": "impressionism",
"Экспрессионизм": "expressionism",
"Сюрреализм": "surrealism",
"Абстракционизм": "abstract art",
"Поп-арт": "pop art",
"Модернизм": "modernism",
"Постмодернизм": "postmodernism",
"Кубизм": "cubism",
"Футуризм": "futurism",
# Эпохи
"Древний мир": "ancient world",
"Средневековье": "middle ages",
"Ренессанс": "renaissance",
"Барокко": "baroque",
"Классицизм": "classicism",
"Романтизм": "romanticism",
"Викторианская эпоха": "victorian era",
"Модерн": "art nouveau",
"Ар-деко": "art deco",
"Современность": "modern era"
}
+4 -1
View File
@@ -3,6 +3,7 @@ from PyQt6.QtWidgets import (QDialog, QVBoxLayout, QHBoxLayout, QTreeWidget,
QScrollArea, QWidget, QCheckBox, QFrame) QScrollArea, QWidget, QCheckBox, QFrame)
from PyQt6.QtCore import Qt, pyqtSignal from PyQt6.QtCore import Qt, pyqtSignal
from .prompt_categories import PROMPT_CATEGORIES from .prompt_categories import PROMPT_CATEGORIES
from .prompt_translations import PROMPT_TRANSLATIONS
class PromptWindow(QDialog): class PromptWindow(QDialog):
prompt_selected = pyqtSignal(str) prompt_selected = pyqtSignal(str)
@@ -195,5 +196,7 @@ class PromptWindow(QDialog):
def add_selected(self): def add_selected(self):
"""Добавление выбранных промптов""" """Добавление выбранных промптов"""
if self.selected_prompts: if self.selected_prompts:
prompts_text = ", ".join(sorted(self.selected_prompts)) # Преобразуем русские названия в английские
translated_prompts = [PROMPT_TRANSLATIONS.get(prompt, prompt) for prompt in self.selected_prompts]
prompts_text = ", ".join(sorted(translated_prompts))
self.prompt_selected.emit(prompts_text) self.prompt_selected.emit(prompts_text)
+93
View File
@@ -0,0 +1,93 @@
from PyQt6.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLabel, QFrame
from PyQt6.QtCore import Qt, pyqtSignal
from .size_presets import SIZE_PRESETS
class SizePresetManager(QWidget):
size_changed = pyqtSignal(int, int) # Сигнал для изменения размера
def __init__(self, parent=None):
super().__init__(parent)
self.setup_ui()
def setup_ui(self):
layout = QVBoxLayout(self)
layout.setSpacing(2)
# Заголовок
title = QLabel("Размеры:")
title.setStyleSheet("""
QLabel {
color: #ffffff;
font-size: 12px;
font-weight: bold;
padding: 4px;
background-color: #3b3b3b;
border-radius: 4px;
}
""")
layout.addWidget(title)
# Создаем фрейм для кнопок
buttons_frame = QFrame()
buttons_frame.setStyleSheet("""
QFrame {
background-color: #2b2b2b;
border: 1px solid #3b3b3b;
border-radius: 4px;
padding: 2px;
}
""")
buttons_layout = QVBoxLayout(buttons_frame)
buttons_layout.setSpacing(2)
# Создаем две строки кнопок
row1_layout = QHBoxLayout()
row2_layout = QHBoxLayout()
# Разделяем пресеты на две группы
presets = list(SIZE_PRESETS.items())
half = len(presets) // 2
# Добавляем кнопки в первую строку
for name, (width, height) in presets[:half]:
button = self.create_preset_button(name, width, height)
row1_layout.addWidget(button)
# Добавляем кнопки во вторую строку
for name, (width, height) in presets[half:]:
button = self.create_preset_button(name, width, height)
row2_layout.addWidget(button)
buttons_layout.addLayout(row1_layout)
buttons_layout.addLayout(row2_layout)
layout.addWidget(buttons_frame)
def create_preset_button(self, name, width, height):
"""Создание кнопки пресета с улучшенным дизайном"""
button = QPushButton(name)
button.setStyleSheet(f"""
QPushButton {{
background-color: #3b3b3b;
color: white;
border: 1px solid #555555;
border-radius: 4px;
padding: 4px;
font-size: 11px;
min-width: 80px;
text-align: center;
}}
QPushButton:hover {{
background-color: #4a4a4a;
border-color: #666666;
}}
QPushButton:pressed {{
background-color: #0d6efd;
border-color: #0b5ed7;
}}
""")
button.clicked.connect(lambda checked, w=width, h=height: self.on_preset_clicked(w, h))
return button
def on_preset_clicked(self, width, height):
"""Обработчик нажатия на кнопку пресета"""
self.size_changed.emit(width, height)
+8
View File
@@ -0,0 +1,8 @@
SIZE_PRESETS = {
"512x768": (512, 768),
"768x512": (768, 512),
"512x512": (512, 512),
"768x432": (768, 432),
"432x768": (432, 768),
"600x800": (600, 800)
}