Переработан интерфейс окна промптов: горизонтальное расположение категорий, добавлены чекбоксы, улучшен поиск, изменен размер окна

This commit is contained in:
kromskii2 committed 2025-03-14 19:42:03 +07:00
1 parent af86c5cc53
commit 657d8b5ec1
1 file changed
+110 -55
+110 -55
View File
@@ -1,5 +1,6 @@
from PyQt6.QtWidgets import (QDialog, QVBoxLayout, QHBoxLayout, QTreeWidget, from PyQt6.QtWidgets import (QDialog, QVBoxLayout, QHBoxLayout, QTreeWidget,
QTreeWidgetItem, QPushButton, QLineEdit, QLabel) QTreeWidgetItem, QPushButton, QLineEdit, QLabel,
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
@@ -10,6 +11,7 @@ class PromptWindow(QDialog):
super().__init__(parent) super().__init__(parent)
self.setWindowTitle("Готовые промпты") self.setWindowTitle("Готовые промпты")
self.setModal(False) self.setModal(False)
self.selected_prompts = set()
self.setup_ui() self.setup_ui()
self.load_categories() self.load_categories()
@@ -17,24 +19,48 @@ class PromptWindow(QDialog):
self.setStyleSheet(""" self.setStyleSheet("""
QDialog { QDialog {
background-color: #2b2b2b; background-color: #2b2b2b;
min-width: 1000px; min-width: 1500px;
min-height: 800px; min-height: 700px;
} }
QTreeWidget { QScrollArea {
background-color: #1e1e1e; background-color: #1e1e1e;
color: #ffffff;
border: 1px solid #3b3b3b; border: 1px solid #3b3b3b;
border-radius: 4px; border-radius: 4px;
padding: 8px; padding: 8px;
}
QScrollArea > QWidget > QWidget {
background-color: #1e1e1e;
}
QLabel {
color: #ffffff;
font-size: 14px; font-size: 14px;
font-weight: bold;
padding: 8px;
background-color: #3b3b3b;
border-radius: 4px;
} }
QTreeWidget::item { QCheckBox {
padding: 6px; color: #ffffff;
min-height: 24px; font-size: 14px;
padding: 4px;
spacing: 8px;
} }
QTreeWidget::item:selected { 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; background-color: #0d6efd;
color: white; border-radius: 3px;
}
QCheckBox::indicator:hover {
border-color: #0b5ed7;
} }
QPushButton { QPushButton {
background-color: #0d6efd; background-color: #0d6efd;
@@ -60,8 +86,10 @@ class PromptWindow(QDialog):
font-size: 14px; font-size: 14px;
min-height: 24px; min-height: 24px;
} }
QLabel { QFrame {
font-size: 14px; background-color: #1e1e1e;
border: 1px solid #3b3b3b;
border-radius: 4px;
} }
""") """)
@@ -76,15 +104,22 @@ class PromptWindow(QDialog):
search_layout.addWidget(self.search_input) search_layout.addWidget(self.search_input)
layout.addLayout(search_layout) layout.addLayout(search_layout)
# Дерево категорий # Горизонтальная прокрутка для категорий
self.tree = QTreeWidget() categories_scroll = QScrollArea()
self.tree.setHeaderLabels(["Категории и промпты"]) categories_scroll.setWidgetResizable(True)
self.tree.itemDoubleClicked.connect(self.on_item_double_clicked) categories_scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOn)
layout.addWidget(self.tree) 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() buttons_layout = QHBoxLayout()
add_button = QPushButton("Добавить выбранное") add_button = QPushButton("Добавить выбранные")
add_button.clicked.connect(self.add_selected) add_button.clicked.connect(self.add_selected)
close_button = QPushButton("Закрыть") close_button = QPushButton("Закрыть")
close_button.clicked.connect(self.close) close_button.clicked.connect(self.close)
@@ -93,52 +128,72 @@ class PromptWindow(QDialog):
layout.addLayout(buttons_layout) layout.addLayout(buttons_layout)
def load_categories(self): def load_categories(self):
"""Загрузка категорий и промптов в дерево""" """Загрузка категорий и промптов"""
for category, subcategories in PROMPT_CATEGORIES.items(): for category, subcategories in PROMPT_CATEGORIES.items():
category_item = QTreeWidgetItem([category]) # Создаем фрейм для категории
self.tree.addTopLevelItem(category_item) 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(): for subcategory, prompts in subcategories.items():
subcategory_item = QTreeWidgetItem([subcategory]) # Добавляем заголовок подкатегории
category_item.addChild(subcategory_item) subcategory_label = QLabel(subcategory)
subcategories_layout.addWidget(subcategory_label)
# Добавляем чекбоксы для промптов
for prompt in prompts: for prompt in prompts:
prompt_item = QTreeWidgetItem([prompt]) checkbox = QCheckBox(prompt)
subcategory_item.addChild(prompt_item) checkbox.stateChanged.connect(lambda state, p=prompt: self.on_checkbox_changed(state, p))
subcategories_layout.addWidget(checkbox)
self.tree.expandAll() 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): def filter_prompts(self, text):
"""Фильтрация промптов по поисковому запросу""" """Фильтрация промптов по поисковому запросу"""
text = text.lower() text = text.lower()
self.tree.clear() for i in range(self.categories_layout.count()):
self.load_categories() category_frame = self.categories_layout.itemAt(i).widget()
for j in range(category_frame.layout().count()):
if not text: widget = category_frame.layout().itemAt(j).widget()
return if isinstance(widget, QScrollArea):
scroll_widget = widget.widget()
def filter_items(item): for k in range(scroll_widget.layout().count()):
if item.childCount() == 0: # Это промпт sub_widget = scroll_widget.layout().itemAt(k).widget()
return text in item.text(0).lower() if isinstance(sub_widget, QCheckBox):
else: # Это категория sub_widget.setVisible(text in sub_widget.text().lower())
has_visible_children = False elif isinstance(sub_widget, QLabel):
for i in range(item.childCount()): # Показываем/скрываем заголовок подкатегории в зависимости от видимости его промптов
if filter_items(item.child(i)): has_visible_prompts = False
has_visible_children = True for l in range(k + 1, scroll_widget.layout().count()):
if not has_visible_children: next_widget = scroll_widget.layout().itemAt(l).widget()
item.parent().removeChild(item) if isinstance(next_widget, QCheckBox) and next_widget.isVisible():
return has_visible_children has_visible_prompts = True
break
for i in range(self.tree.topLevelItemCount()): sub_widget.setVisible(has_visible_prompts)
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): def add_selected(self):
"""Добавление выбранного промпта""" """Добавление выбранных промптов"""
selected_items = self.tree.selectedItems() if self.selected_prompts:
if selected_items and selected_items[0].childCount() == 0: prompts_text = ", ".join(sorted(self.selected_prompts))
self.prompt_selected.emit(selected_items[0].text(0)) self.prompt_selected.emit(prompts_text)