重构渲染逻辑

This commit is contained in:
yuruo
2024-05-17 20:19:02 +08:00
parent 7b8d31c5dc
commit 44e472af27
7 changed files with 67 additions and 62 deletions

View File

@@ -32,13 +32,7 @@ class ActionBase(BaseModel):
self._is_config_page_init = False
# 如果拖动过 action则使用传进来的 output_save_name
self._output_save_name_from_drag = output_save_name_from_drag
self._data = {}
def set_data(self, key, value):
self._data[key] = value
def get_data(self, key):
return self._data.get(key, None)
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

View File

@@ -1,5 +1,6 @@
import pickle
from typing import List
from PyQt6 import QtCore
from PyQt6.QtCore import Qt, QMimeData, QByteArray, QPoint, pyqtSignal
from PyQt6.QtGui import QDrag
from PyQt6.QtWidgets import QListWidget, QApplication, QStyle, QMenu
@@ -34,45 +35,37 @@ class ActionList(QListWidget):
self.offset = 19
self.init()
self._parent = parent_widget
self._data = {}
self.action_signal = ActionSignal()
if not action_list_items:
action_list_items = []
for action_list_item in action_list_items:
self.get_edit_page().q_undo_stack.push(ActionListAddCommand(self, action_list_item.action.action_pos, action_list_item))
action_list_item.render()
# action_list_item.render()
def add_action_list_items(self, action_list_items):
for action_list_item in action_list_items:
self.get_edit_page().q_undo_stack.push(ActionListAddCommand(self, action_list_item.action.action_pos, action_list_item))
action_list_item.render()
# action_list_item.render()
# 当 item 数量发生变化时,更新组件样式
def adjust_ui(self):
if self.get_data("type") == "include":
total_height = 0
for item in self.get_action_list_items(self):
total_height += self.visualItemRect(item).height()
# 内圈大小
self.setFixedHeight(20 if total_height + 5 < 20 else total_height + 5)
# 面板大小
self.parent().setFixedHeight(total_height + 5)
self.action_signal.emit()
def set_data(self, key, value):
self._data[key] = value
def get_data(self, key):
return self._data.get(key, None)
if self.level == 0:
return
total_height = 0
for item in self.get_action_list_items(self):
total_height += self.visualItemRect(item).height()
# 内圈大小
self.setFixedHeight(20 if total_height + 5 < 20 else total_height + 5)
self.action_signal.size_changed_emit()
@classmethod
def load(cls, actions_raw_data: List[dict], edit_page):
def load(cls, actions_raw_data: List[dict], parent, level=0):
action_list_items = [ActionListItem.load(i) for i in actions_raw_data]
action_list = ActionList(action_list_items, level=0, parent_widget=edit_page)
action_list = ActionList(action_list_items, level=level, parent_widget=parent)
for action_list_item in action_list_items:
action_list_item.set_parent(action_list)
# action_list_item.render()
action_list_item.render()
action_list_item.action_signal.size_changed.connect(action_list.adjust_ui)
return action_list
@@ -153,7 +146,8 @@ class ActionList(QListWidget):
def mouseReleaseEvent(self, e):
# 鼠标release时才选中
index = self.indexAt(e.pos())
self.clear_selection(index)
self.clear_selection()
self.setCurrentIndex(index)
def mouseMoveEvent(self, e):
# 如果在历史事件中左键点击过
@@ -165,7 +159,8 @@ class ActionList(QListWidget):
self.the_drag_row = the_drag_index.row()
self.the_selected_row = self.currentIndex().row()
# 拖拽即选中
self.clear_selection(the_drag_index)
self.clear_selection()
self.setCurrentIndex(the_drag_index)
the_drag_item = self.item(the_drag_index.row())
assert isinstance(the_drag_item, ActionListItem)
# 把拖拽数据放在QMimeData容器中
@@ -280,7 +275,8 @@ class ActionList(QListWidget):
# todo 使用 action move command
self.get_edit_page().q_undo_stack.push(ActionListAddCommand(self, self.the_insert_row, drag_action_item))
# 选中当前行
self.clear_selection(QListWidget().currentIndex())
self.clear_selection()
self.setCurrentIndex(QListWidget().currentIndex())
e.setDropAction(Qt.DropAction.MoveAction)
e.accept()
@@ -290,13 +286,13 @@ class ActionList(QListWidget):
if iter_way == "son":
for i in range(action_list.count()):
item = action_list.item(i)
if item.action.get_data("action_list") is not None:
cls.iter_include_action_list(item.action.get_data("action_list"), action, iter_way)
if item.type == "include":
cls.iter_include_action_list(item.data(QtCore.Qt.ItemDataRole.UserRole), action, iter_way)
elif iter_way == "parent":
# 取消选中父组件
if isinstance(action_list.get_parent(), ActionBase):
parent_action_list = action_list.get_parent().get_action_list()
parent_action_list = action_list.get_parent()
cls.iter_include_action_list(parent_action_list, action, iter_way)
def run(self):
@@ -310,13 +306,16 @@ class ActionList(QListWidget):
# 取消选中
def clear_selection(self, index):
def clear(action_list):
action_list.setCurrentRow(-1)
# 刷新
action_list.update()
# 取消选中
self.iter_include_action_list(self, clear, "parent")
self.iter_include_action_list(self, clear, "son")
# 选中当前行
self.setCurrentIndex(index)
def clear_selection(self):
self.setCurrentRow(-1)
self.update()
self.action_signal.cancel_selection_emit()
# def clear(action_list):
# action_list.setCurrentRow(-1)
# # 刷新
# action_list.update()
# # 取消选中
# self.iter_include_action_list(self, clear, "parent")
# self.iter_include_action_list(self, clear, "son")
# # 选中当前行
# self.setCurrentIndex(index)

View File

@@ -1,4 +1,5 @@
import uuid
from PyQt6.QtWidgets import QListWidgetItem
from PyQt6 import QtCore, QtWidgets
from actions.action_base import ActionBase
@@ -11,6 +12,7 @@ class ActionListItem(QListWidgetItem):
def __init__(self, action: ActionBase, widget_parent=None, *args, **kwargs):
super().__init__(*args, **kwargs)
self.action = action
self.type = self.action.action_type
self.setText(action.name)
self._parent = widget_parent
self.action_signal = ActionSignal()
@@ -18,7 +20,7 @@ class ActionListItem(QListWidgetItem):
# 当父元素是包含类型的组件,减少当前元素的宽度让其能够被包含
def render(self):
if self.action.action_type == "include":
if self.type == "include":
widget = QtWidgets.QWidget()
widget.setStyleSheet("background-color: white;")
label = QtWidgets.QLabel()
@@ -30,18 +32,19 @@ class ActionListItem(QListWidgetItem):
widget.setFixedHeight(60)
widget.setFixedWidth(self.get_parent().width() - 10)
from actions.action_list import ActionList
sub_action_list = ActionList(parent_widget=self.action, level=self.get_parent().level + 1)
sub_action_list.action_signal.size_changed.connect(self._adjust_ui)
sub_action_list.set_data("type", "include")
sub_action_list.setGeometry(QtCore.QRect(20, 30, widget.width() - 20, 20))
layout.addWidget(sub_action_list)
action_list = ActionList.load(self.action.args.action_list, self.get_parent(), self.get_parent().level + 1)
action_list.action_signal.size_changed.connect(self._adjust_ui)
action_list.action_signal.cancel_selection.connect(self.get_parent().clear_selection)
action_list.setGeometry(QtCore.QRect(20, 30, widget.width() - 20, 20))
self.setData(QtCore.Qt.ItemDataRole.UserRole, action_list)
layout.addWidget(action_list)
self.setSizeHint(widget.size())
self.action.set_data("action_list", sub_action_list)
self.get_parent().setItemWidget(self, widget)
# 根据子元素数量调整当前元素尺寸大小
def _adjust_ui(self):
action_list = self.action.get_data("action_list")
action_list = self.data(QtCore.Qt.ItemDataRole.UserRole)
total_height = 0
for item in action_list.get_action_list_items(action_list):
total_height += action_list.visualItemRect(item).height()
@@ -49,7 +52,7 @@ class ActionListItem(QListWidgetItem):
self.setSizeHint(QtCore.QSize(action_list.width(), total_height + 60))
self.get_widget().setFixedHeight(total_height + 60)
# 发送元素大小更新的信号给父元素
self.action_signal.emit()
self.action_signal.size_changed_emit()
def ActionListItem(self, parent):
self._parent = parent

View File

@@ -2,10 +2,13 @@ from PyQt6.QtCore import QObject, pyqtSignal
class ActionSignal(QObject):
size_changed = pyqtSignal()
cancel_selection = pyqtSignal()
def __init__(self):
super().__init__()
def emit(self):
def size_changed_emit(self):
self.size_changed.emit()
def cancel_selection_emit(self):
self.cancel_selection.emit()

View File

@@ -56,10 +56,11 @@ def load():
if __name__ == "__main__":
logging.basicConfig(level=logging.DEBUG)
sys.excepthook = excepthook
app = QApplication(sys.argv)
load()
page = ChatPage()
page.show()
print(sys.exit(app.exec()))
logging.error(sys.exit(app.exec()))

View File

@@ -32,9 +32,10 @@ class EditPage(QMainWindow, interface_ui):
# 保存action的输出结果
self.output_save_dict = output_save_dict
self.send_to_ai_selection_text = send_to_ai_selection_text
self.all_action_list = []
if not action_list:
action_list = ActionList(parent_widget=self)
self.action_list = action_list
self.set_action_list(action_list)
self.q_undo_stack = QUndoStack()
redo_action = self.q_undo_stack.createRedoAction(self, "Redo")
redo_action.setShortcut(QKeySequence.StandardKey.Redo)
@@ -44,6 +45,7 @@ class EditPage(QMainWindow, interface_ui):
self.addAction(undo_action)
self.setupUi(self)
self.setup_up()
def closeEvent(self, event):
self.page_closed.emit(self.func_name)
@@ -78,6 +80,13 @@ class EditPage(QMainWindow, interface_ui):
self.run_output_layout.setAlignment(Qt.AlignmentFlag.AlignTop)
self.send_to_ai_selection.setCurrentText(self.send_to_ai_selection_text)
def set_action_list(self, action_list):
self.action_list = action_list
self.all_action_list = [action_list]
def add_action_list(self, action_list):
self.all_action_list.append(action_list)
# 将返回结果发送到 ai
def update_send_to_ai_selection(self):
self.send_to_ai_selection.clear()
@@ -139,7 +148,7 @@ class EditPage(QMainWindow, interface_ui):
output_save_dict=edit_page_json["output_save_dict"],
send_to_ai_selection_text=edit_page_json["send_to_ai_selection_text"]
)
action_list = ActionList.load(actions_raw_data=edit_page_json["action_list"], edit_page=edit_page)
action_list = ActionList.load(actions_raw_data=edit_page_json["action_list"], parent=edit_page)
edit_page.action_list = action_list
edit_page.update_runing_terminal()
action_list.setParent(edit_page)

View File

@@ -12,9 +12,8 @@ class ActionListAddCommand(QUndoCommand):
def redo(self):
self.action_list.insertItem(self.row, self.action_item)
if self.action_list.get_data("type") == "include":
parent_args = self.action_list.get_parent().args
parent_args.action_list.insert(self.row, self.action_item.action)
self.action_item.render()
# 不是顶层调整UI大小
if self.action_list.level > 0:
self.action_list.adjust_ui()
@@ -22,9 +21,6 @@ class ActionListAddCommand(QUndoCommand):
def undo(self):
self.action_list.takeItem(self.row)
if self.action_list.get_data("type") == "include":
parent_args = self.action_list.get_parent().args
parent_args.action_list.remove(self.action_item.action)
# 不是顶层调整UI大小
if self.action_list.level > 0:
self.action_list.adjust_ui()