From e376be3daa70f9a0deda4f98cf9c40417304f161 Mon Sep 17 00:00:00 2001 From: Vladislav Samorodov Date: Mon, 28 Oct 2024 02:02:02 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=BE=D0=BA=D0=BD=D0=B0=20=D0=BF=D0=BE?= =?UTF-8?q?=D0=B4=D1=82=D0=B2=D0=B5=D1=80=D0=B6=D0=B4=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Окно теперь может быть отредактировано в размерах, добавлен скрол. Более корректная отработка подтверждения --- main.py | 61 +++++++++++++++++++++++++++++++++++++++------------------ mind.py | 35 +++++++++++++++++++++------------ 2 files changed, 64 insertions(+), 32 deletions(-) diff --git a/main.py b/main.py index d3a258c..a4c70d4 100644 --- a/main.py +++ b/main.py @@ -2,7 +2,7 @@ from PyQt6.QtCore import QObject, pyqtSignal, pyqtSlot, QEventLoop, Qt from PyQt6.QtGui import QIcon -from PyQt6.QtWidgets import QApplication, QWidget, QHBoxLayout, QVBoxLayout, QLabel, QFrame, QMessageBox +from PyQt6.QtWidgets import QApplication, QWidget, QHBoxLayout, QVBoxLayout, QLabel, QFrame, QMessageBox, QDialog, QPushButton, QScrollArea from qfluentwidgets import * from qframelesswindow.utils import getSystemAccentColor @@ -55,26 +55,49 @@ def __init__(self, parent=None): self.stackedWidget.setStyleSheet('QWidget{background: transparent}') # Подключаем сигнал к слоту self.mind.confirmation_needed.connect(self.handle_confirmation_needed) + # self.mind.confirmation_result.connect(self.handle_confirmation_result) - @pyqtSlot(str, object) - def handle_confirmation_needed(self, check_response, result_holder): - # Создаём диалоговое окно предупреждения - msg_box = QMessageBox(self) - msg_box.setIcon(QMessageBox.Icon.Warning) - msg_box.setWindowTitle("Предупреждение безопасности") - msg_box.setText("Код не прошёл проверку безопасности.") - msg_box.setInformativeText(f"{check_response}\n\nВы хотите выполнить этот код?") + @pyqtSlot(str) + def handle_confirmation_needed(self, message): + dialog = ConfirmationDialog(message, self) + confirmed = dialog.exec() == QDialog.DialogCode.Accepted + self.mind.confirmation_result.emit(confirmed) - msg_box.setStandardButtons(QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No) - msg_box.setDefaultButton(QMessageBox.StandardButton.No) - - # Показываем диалог и получаем ответ - ret = msg_box.exec() - - if ret == QMessageBox.StandardButton.Yes: - result_holder['confirmed'] = True - else: - result_holder['confirmed'] = False +class ConfirmationDialog(QDialog): + def __init__(self, message, parent=None): + super().__init__(parent) + self.setWindowTitle("Предупреждение безопасности") + self.setMinimumSize(400, 300) + self.resize(600, 400) # Начальный размер + + layout = QVBoxLayout(self) + + # Создаем прокручиваемую область + scroll = QScrollArea(self) + scroll.setWidgetResizable(True) + + # Создаем виджет с текстом + content = QWidget() + scroll_layout = QVBoxLayout(content) + label = QLabel(message) + label.setWordWrap(True) + scroll_layout.addWidget(label) + scroll.setWidget(content) + + layout.addWidget(scroll) + + # Кнопки Yes и No + button_layout = QHBoxLayout() + self.yes_button = QPushButton("Yes") + self.no_button = QPushButton("No") + button_layout.addStretch() + button_layout.addWidget(self.yes_button) + button_layout.addWidget(self.no_button) + layout.addLayout(button_layout) + + # Подключаем сигналы + self.yes_button.clicked.connect(self.accept) + self.no_button.clicked.connect(self.reject) class Chat(QWidget): diff --git a/mind.py b/mind.py index e9413ba..e87d565 100644 --- a/mind.py +++ b/mind.py @@ -63,13 +63,17 @@ def answer(): class Mind(QObject): # Сигнал для запроса подтверждения, передаёт строку с сообщением и объект для возврата результата - confirmation_needed = pyqtSignal(str, object) + + confirmation_needed = pyqtSignal(str) + confirmation_result = pyqtSignal(bool) def __init__(self, parent_widget=None): super().__init__() self.init_new_chat() - self.parent_widget = parent_widget # Сохраняем родительский виджет для диалогов - + self.parent_widget = parent_widget + self.confirmation_result.connect(self.handle_confirmation_result) + self.pending_execution = None # Хранение информации о том, что нужно выполнить после подтверждения + def init_new_chat(self): self.messages_array = [ {"role": "user", "content": init_message}, @@ -82,7 +86,7 @@ def get_ai_response(self, input_string, card): self.thread.start() def response_thread(self, card, input_string): - max_retries = 3 # Максимальное количество повторных попыток + max_retries = 5 # Максимальное количество повторных попыток retry_count = 0 while retry_count < max_retries: @@ -157,16 +161,12 @@ def code_exec_result(self, input_str, card, user_input): # Проверяем, есть ли проблемы только с безопасностью if "безопасность" in check_response.lower(): # Спрашиваем пользователя о подтверждении выполнения - loop = QEventLoop() - result_holder = {'confirmed': None} - - def on_confirmation_received(confirmed): - result_holder['confirmed'] = confirmed - loop.quit() + self.pending_execution = (code, card) + self.confirmation_needed.emit(check_response) - # Эмитируем сигнал и подключаем слот - self.confirmation_needed.emit(check_response, result_holder) + '''# Подключаем слот перед эмиссией сигнала self.confirmation_needed.connect(on_confirmation_received, Qt.ConnectionType.DirectConnection) + self.confirmation_needed.emit(check_response, result_holder) # Запускаем цикл ожидания loop.exec() @@ -177,7 +177,7 @@ def on_confirmation_received(confirmed): else: # Пользователь отказался card.set_content(Message(text="Операция отменена пользователем.")) - return True # Считаем, что попытка успешна, но код не выполнен + return True # Считаем, что попытка успешна, но код не выполнен''' else: # Проблемы не только с безопасностью, пытаемся решить проблему clarification = f"Код не прошёл проверку: {check_response}. Попробуй исправить код и решить задачу '{user_input}' ещё раз." @@ -190,6 +190,15 @@ def on_confirmation_received(confirmed): result = f"Ошибка выполнения кода: {e}" card.set_content(Message(text=result)) return True # Считаем попытку успешной, несмотря на ошибку + @pyqtSlot(bool) + def handle_confirmation_result(self, confirmed): + if self.pending_execution: + code, card = self.pending_execution + if confirmed: + self.execute_code(code, card) + else: + card.set_content(Message(text="Операция отменена пользователем.")) + self.pending_execution = None def execute_code(self, code, card): try: