Files
art/modules/prompt_window.py

199 lines
8.2 KiB
Python

from PyQt6.QtWidgets import (QDialog, QVBoxLayout, QHBoxLayout, QTreeWidget,
QTreeWidgetItem, QPushButton, QLineEdit, QLabel,
QScrollArea, QWidget, QCheckBox, QFrame)
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.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 #0d6efd;
background-color: #0d6efd;
border-radius: 3px;
}
QCheckBox::indicator:hover {
border-color: #0b5ed7;
}
QPushButton {
background-color: #0d6efd;
color: white;
border: none;
border-radius: 4px;
padding: 8px 16px;
font-weight: bold;
min-width: 120px;
}
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;
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 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:
prompts_text = ", ".join(sorted(self.selected_prompts))
self.prompt_selected.emit(prompts_text)