diff --git a/actions/action_base.py b/actions/action_base.py index 2de8db0..a609101 100644 --- a/actions/action_base.py +++ b/actions/action_base.py @@ -1,45 +1,43 @@ -from typing import Type, Any, ClassVar -import uuid - -from PyQt6.QtCore import Qt +from typing import Type, Any +from PyQt6.QtCore import Qt, pyqtSignal, QObject from PyQt6.QtWidgets import QHBoxLayout, QLabel, QLineEdit, QPushButton from pydantic import BaseModel -from utils.global_util import GlobalUtil from utils.qt_util import QtUtil -from utils.undo_command import ActionListAddCommand +from PyQt6.QtCore import QThread +class ActionSignal(QObject): + finish_run_signal = pyqtSignal(object) + start_run_signal = pyqtSignal() + + def finish_run_signal_emit(self, res): + self.finish_run_signal.emit(res) + + def start_run_signal_emit(self): + self.start_run_signal.emit() + +class RunActionThread(QThread): + def __init__(self, action): + super().__init__() + self.action = action + + def run(self): + res = self.action.run_with_out_arg() + self.action.get_signal().finish_run_signal_emit(res) class ActionBase(BaseModel): name: str = "" description: str = "" - # 用于标识 action 类型,include 和 single 两种类型 - action_type: str = "" args: Type[BaseModel] - output_save_name: str = "" - action_pos: int = -1 - action_level: int = -1 - uuid: str = "" - parent_uuid: str = "" - - def __init__(self, output_save_name_from_drag: str = None, **data: Any): + + def __init__(self, **data: Any): super().__init__(**data) - # 为每个实例生成唯一的 UUID - self.uuid = str(uuid.uuid4()) self._ui_name_and_line_edit = {} - self._output_edit = None self._config_ui = QtUtil.load_ui("action_config_page.ui") - self._parent = None - self._is_config_page_init = False - # 如果拖动过 action,则使用传进来的 output_save_name - self._output_save_name_from_drag = output_save_name_from_drag - - - def set_output_save_name_from_drag(self, output_save_name_from_drag: str): - self._output_save_name_from_drag = output_save_name_from_drag + self._action_signal = ActionSignal() + def get_signal(self): + return self._action_signal - def get_parent(self): - return GlobalUtil.get_widget_by_uuid(self.parent_uuid, "action_list_item") def run(self, *args, **kwargs): raise TypeError("Not realize run function") @@ -47,10 +45,10 @@ class ActionBase(BaseModel): def run_with_out_arg(self): print("运行中...") res = self.run(**self.args.model_dump()) - # 保存输出结果 - if self.output_save_name: - GlobalUtil.current_page.output_save_dict[self.uuid][self.output_save_name] = res - GlobalUtil.current_page.update_runing_terminal() + # # 保存输出结果 + # if self.output_save_name: + # GlobalUtil.current_page.output_save_dict[self.uuid][self.output_save_name] = res + # GlobalUtil.current_page.update_runing_terminal() return res # 设置配置界面的布局 @@ -72,75 +70,17 @@ class ActionBase(BaseModel): self._ui_name_and_line_edit[field] = line_edit - - def save_out_put_ui(self): - # 判断是否需要保存输出 - if self.output_save_name != "": - output_label = QLabel(self._config_ui) - output_label.setText("保存结果至") - output_line_edit = QLineEdit("output_save_name") - self._output_edit = output_line_edit - # 使用外部传进来的 output_save_name - if self._output_save_name_from_drag: - self.output_save_name = self._output_save_name_from_drag - # 设置编辑框的默认名称 - output_line_edit.setText(self.output_save_name) - else: - output_save_name = self.output_save_name - # 为输出结果自动取名 - i = 1 - # 获取 editPage 页面的 output_save_dict - output_save_dict = GlobalUtil.current_page.get_output_dict() - # 找到一个不存在的名称 - while True: - if output_save_name in output_save_dict.keys(): - output_save_name = self.output_save_name + "_" + str(i) - i += 1 - continue - else: - self.output_save_name = output_save_name - # 设置编辑框的默认名称 - output_line_edit.setText(output_save_name) - break - self._config_ui.output_config.addWidget(output_label) - self._config_ui.output_config.addWidget(output_line_edit) - else: - - self._config_ui.output_config.addWidget(QLabel("当前行为不包含输出项")) - def __cancel_button_clicked(self): self._config_ui.hide() - def get_action_list(self): - return self.get_parent().get_parent() - - def get_action_list_item(self): - return self.get_parent() - def _save_button_clicked(self): arg = {} for arg_name in self._ui_name_and_line_edit: arg[arg_name] = self._ui_name_and_line_edit[arg_name].text() self.args = self.args.model_validate(arg) - self.action_level = 0 - # 如果设置了output_save_name,向全局中插入该变量 - if self.output_save_name != "": - self.output_save_name = self._output_edit.text() - GlobalUtil.current_page.output_save_dict[self.uuid] = {} - GlobalUtil.current_page.output_save_dict[self.uuid][self.output_save_name] = "" - GlobalUtil.current_page.update_send_to_ai_selection() - - # 判断 item 是否在 action_list 中 - def item_in_action_list(): - action_list = self.get_action_list() - for item in action_list.get_action_list_items(action_list): - if item == self.get_action_list_item(): - return True - return False - - # 插入新的 acton - if not item_in_action_list(): - GlobalUtil.current_page.q_undo_stack.push(ActionListAddCommand(self.get_action_list(), self.action_pos, self.get_action_list_item())) + thread = RunActionThread(self) + thread.start() + self._action_signal.start_run_signal_emit() self._config_ui.hide() @@ -154,9 +94,6 @@ class ActionBase(BaseModel): # 居上对齐 self._config_ui.config_list.layout().setAlignment(Qt.AlignmentFlag.AlignTop) # 如果配置页面未加载过,就进行加载 - if not self._is_config_page_init: - self.save_out_put_ui() - self.config_page_ui() + self.config_page_ui() # 如果已经加载过,就直接显示 - self._is_config_page_init = True self._config_ui.show() diff --git a/actions/action_list.py b/actions/action_list.py index a79ee04..f96d51b 100644 --- a/actions/action_list.py +++ b/actions/action_list.py @@ -83,7 +83,7 @@ class ActionList(QListWidget): self.setSpacing(1) self.setStyleSheet( "QListView{background:rgb(220,220,220); border:0px; margin:0px 0px 0px 0px;}" - "QListView::Item{height:40px; border:0px; background:rgb(255,255,255);margin-left: 3px;}" + "QListViewf::Item{height:40px; border:0px; background:rgb(255,255,255);margin-left: 3px;}" # "QListView::Item:hover{color:rgba(40, 40, 200, 255); padding-left:14px;})" # 选中时为透明,否则会全白 "QListView::Item:selected{color:rgb(0, 0, 0);outline: none;}" diff --git a/pages/chat_page.py b/pages/chat_page.py index d4d25de..19a8c53 100644 --- a/pages/chat_page.py +++ b/pages/chat_page.py @@ -9,27 +9,38 @@ from pages.config_page import ConfigPage from utils.qt_util import QtUtil class ActionItems(QListWidgetItem): - def __init__(self, action): + def __init__(self, action, chat_page): super().__init__() self.action = action + self.chat_page = chat_page + self.action.get_signal().finish_run_signal.connect(self.save_output) + self.action.get_signal().start_run_signal.connect(self.start_run) # 创建一个 QLabel 作为列表项的小部件 self.label = QLabel() text = f"

{self.action.name}

{self.action.description}

" self.label.setText(text) self.setSizeHint(self.label.sizeHint()) + + def save_output(self, res): + self.chat_page.new_conversation(f"执行成功,执行结果:{str(res)}", "system") + def start_run(self): + self.chat_page.action_list.set_visibility(False) + self.chat_page.chat_input.clear() + self.chat_page.new_conversation(f"执行{self.action.name}动作中:\n执行动作描述:{self.action.description}\n执行参数:{self.action.args}", "system") class ActionList(QListWidget): - def __init__(self, parent=None): + def __init__(self, parent=None, chat_page=None): super().__init__(parent) + self.chat_page = chat_page self.setVisible(False) self.setFocusPolicy(Qt.FocusPolicy.TabFocus) actions = ActionUtil.get_funcs() self.setSpacing(3) for i in range(len(actions)): action = actions[i] - item = ActionItems(action(args={})) + item = ActionItems(action(args={}), chat_page=self.chat_page) self.insertItem(i, item) self.setItemWidget(item, item.label) @@ -150,14 +161,14 @@ class ChatPage(QMainWindow, interface_ui): def setup_up(self): # self = QtUtil.load_ui("chat_page.ui") - chat_input = ChatInput(parent=self.centralwidget, chat_page=self) - chat_input.setGeometry(QtCore.QRect(40, 580, 601, 51)) - chat_input.setStyleSheet("border-radius: 30px") - chat_input.setObjectName("chat_input") - chat_input.setPlaceholderText("请输入“/”,选择运行的指令") + self.chat_input = ChatInput(parent=self.centralwidget, chat_page=self) + self.chat_input.setGeometry(QtCore.QRect(40, 580, 601, 51)) + self.chat_input.setStyleSheet("border-radius: 30px") + self.chat_input.setObjectName("chat_input") + self.chat_input.setPlaceholderText("请输入“/”,选择运行的指令") self.chat_list = ChatList(parent=self.centralwidget, chat_page=self) - self.action_list = ActionList(parent=self.centralwidget) + self.action_list = ActionList(parent=self.centralwidget, chat_page=self) self.action_list.setGeometry(QtCore.QRect(40, 390, 251, 181)) self.action_list.setStyleSheet("border: none;") self.action_list.setObjectName("action_list")