mirror of
https://github.com/goldenfishs/MRobot.git
synced 2026-04-01 05:17:13 +08:00
添加ioc和自动任务
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
from PyQt5.QtWidgets import QDialog, QVBoxLayout, QHBoxLayout, QWidget, QScrollArea
|
||||
from qfluentwidgets import (
|
||||
BodyLabel, TitleLabel, HorizontalSeparator, PushButton, PrimaryPushButton,
|
||||
LineEdit, SpinBox, DoubleSpinBox, CheckBox, TextEdit
|
||||
LineEdit, SpinBox, DoubleSpinBox, CheckBox, TextEdit, ComboBox
|
||||
)
|
||||
from qfluentwidgets import theme, Theme
|
||||
import yaml
|
||||
@@ -76,12 +76,20 @@ class TaskConfigDialog(QDialog):
|
||||
self.add_btn = PrimaryPushButton("创建新任务")
|
||||
self.add_btn.setAutoDefault(False) # 禁止回车触发
|
||||
self.add_btn.setDefault(False)
|
||||
|
||||
# 新增:预设任务按钮
|
||||
self.preset_btn = PushButton("使用预设任务")
|
||||
self.preset_btn.setAutoDefault(False)
|
||||
self.preset_btn.setDefault(False)
|
||||
|
||||
self.del_btn = PushButton("删除当前任务")
|
||||
self.del_btn.setAutoDefault(False) # 禁止回车触发
|
||||
self.del_btn.setDefault(False)
|
||||
self.add_btn.clicked.connect(self.add_task)
|
||||
self.preset_btn.clicked.connect(self.add_preset_task)
|
||||
self.del_btn.clicked.connect(self.delete_current_task)
|
||||
btn_layout.addWidget(self.add_btn)
|
||||
btn_layout.addWidget(self.preset_btn)
|
||||
btn_layout.addWidget(self.del_btn)
|
||||
btn_layout.addStretch() # 添加/删除靠左,stretch在中间
|
||||
|
||||
@@ -135,6 +143,274 @@ class TaskConfigDialog(QDialog):
|
||||
self.task_btn_layout.addWidget(btn)
|
||||
self.task_btn_layout.addStretch()
|
||||
|
||||
def get_preset_tasks(self):
|
||||
"""获取所有可用的预设任务"""
|
||||
from app.tools.code_generator import CodeGenerator
|
||||
task_dir = CodeGenerator.get_assets_dir("User_code/task/template_task")
|
||||
preset_tasks = []
|
||||
|
||||
if not os.path.exists(task_dir):
|
||||
return preset_tasks
|
||||
|
||||
for filename in os.listdir(task_dir):
|
||||
if filename.endswith('.c') and not filename.endswith('.template'):
|
||||
task_name = os.path.splitext(filename)[0]
|
||||
preset_tasks.append(task_name)
|
||||
|
||||
return preset_tasks
|
||||
|
||||
def load_preset_task_config(self, task_name):
|
||||
"""从 yaml 配置文件中加载预设任务的配置"""
|
||||
try:
|
||||
from app.tools.code_generator import CodeGenerator
|
||||
template_dir = CodeGenerator.get_assets_dir("User_code/task/template_task")
|
||||
config_file = os.path.join(template_dir, "task.yaml")
|
||||
|
||||
if not os.path.exists(config_file):
|
||||
return None
|
||||
|
||||
with open(config_file, 'r', encoding='utf-8') as f:
|
||||
config_data = yaml.safe_load(f)
|
||||
|
||||
if config_data and task_name in config_data:
|
||||
return config_data[task_name]
|
||||
return None
|
||||
except Exception as e:
|
||||
print(f"加载预设任务配置失败: {e}")
|
||||
return None
|
||||
|
||||
def load_preset_task_code(self, task_name):
|
||||
"""加载预设任务的代码内容"""
|
||||
from app.tools.code_generator import CodeGenerator
|
||||
task_dir = CodeGenerator.get_assets_dir("User_code/task/template_task")
|
||||
task_file = os.path.join(task_dir, f"{task_name}.c")
|
||||
|
||||
if os.path.exists(task_file):
|
||||
with open(task_file, 'r', encoding='utf-8') as f:
|
||||
return f.read()
|
||||
return None
|
||||
|
||||
def add_preset_task(self):
|
||||
"""添加预设任务"""
|
||||
preset_tasks = self.get_preset_tasks()
|
||||
if not preset_tasks:
|
||||
InfoBar.warning(
|
||||
title="无预设任务",
|
||||
content="未找到可用的预设任务模板",
|
||||
parent=self,
|
||||
duration=2000
|
||||
)
|
||||
return
|
||||
|
||||
# 创建自适应主题的对话框
|
||||
dialog = QDialog(self)
|
||||
dialog.setWindowTitle("选择预设任务")
|
||||
dialog.resize(600, 500)
|
||||
dialog.setModal(True)
|
||||
|
||||
layout = QVBoxLayout(dialog)
|
||||
layout.setContentsMargins(24, 24, 24, 24)
|
||||
layout.setSpacing(18)
|
||||
|
||||
# 固定内容区域
|
||||
fixed_content = QWidget()
|
||||
fixed_content.setFixedHeight(180) # 减少固定高度
|
||||
fixed_layout = QVBoxLayout(fixed_content)
|
||||
fixed_layout.setContentsMargins(0, 0, 0, 0)
|
||||
fixed_layout.setSpacing(18)
|
||||
|
||||
# 标题
|
||||
title_label = TitleLabel("选择预设任务模板")
|
||||
fixed_layout.addWidget(title_label)
|
||||
|
||||
# 说明文字
|
||||
desc_label = BodyLabel("选择一个预设任务模板,系统将自动复制相应的代码和配置")
|
||||
fixed_layout.addWidget(desc_label)
|
||||
|
||||
fixed_layout.addWidget(HorizontalSeparator())
|
||||
|
||||
# 任务选择
|
||||
select_layout = QHBoxLayout()
|
||||
select_layout.setSpacing(12)
|
||||
|
||||
select_label = BodyLabel("预设任务:")
|
||||
preset_combo = ComboBox()
|
||||
preset_combo.addItems(preset_tasks)
|
||||
preset_combo.setCurrentIndex(0)
|
||||
preset_combo.setMinimumWidth(160)
|
||||
|
||||
select_layout.addWidget(select_label)
|
||||
select_layout.addWidget(preset_combo)
|
||||
select_layout.addStretch()
|
||||
|
||||
fixed_layout.addLayout(select_layout)
|
||||
|
||||
# 参数信息 - 单行显示
|
||||
params_layout = QHBoxLayout()
|
||||
params_layout.setSpacing(24) # 适中的间距
|
||||
|
||||
self.info_freq = BodyLabel("")
|
||||
self.info_delay = BodyLabel("")
|
||||
self.info_stack = BodyLabel("")
|
||||
self.info_ctrl = BodyLabel("")
|
||||
|
||||
self.info_freq.setMinimumWidth(120)
|
||||
self.info_delay.setMinimumWidth(100)
|
||||
self.info_stack.setMinimumWidth(120)
|
||||
self.info_ctrl.setMinimumWidth(100)
|
||||
|
||||
params_layout.addWidget(self.info_freq)
|
||||
params_layout.addWidget(self.info_delay)
|
||||
params_layout.addWidget(self.info_stack)
|
||||
params_layout.addWidget(self.info_ctrl)
|
||||
params_layout.addStretch()
|
||||
|
||||
fixed_layout.addLayout(params_layout)
|
||||
fixed_layout.addStretch() # 在固定区域内保持紧凑
|
||||
|
||||
layout.addWidget(fixed_content)
|
||||
|
||||
# 弹性描述区域
|
||||
desc_layout = QVBoxLayout()
|
||||
desc_layout.setSpacing(8)
|
||||
|
||||
desc_title = BodyLabel("描述:")
|
||||
desc_title.setStyleSheet("font-weight: bold;")
|
||||
desc_layout.addWidget(desc_title)
|
||||
|
||||
self.preview_desc = TextEdit()
|
||||
self.preview_desc.setReadOnly(True)
|
||||
self.preview_desc.setMinimumHeight(60) # 最小高度
|
||||
desc_layout.addWidget(self.preview_desc)
|
||||
|
||||
layout.addLayout(desc_layout, stretch=1) # 弹性伸缩
|
||||
|
||||
# 按钮区域
|
||||
layout.addWidget(HorizontalSeparator())
|
||||
btn_layout = QHBoxLayout()
|
||||
btn_layout.addStretch()
|
||||
|
||||
cancel_btn = PushButton("取消")
|
||||
ok_btn = PrimaryPushButton("确定添加")
|
||||
|
||||
cancel_btn.clicked.connect(dialog.reject)
|
||||
ok_btn.clicked.connect(dialog.accept)
|
||||
|
||||
btn_layout.addWidget(cancel_btn)
|
||||
btn_layout.addWidget(ok_btn)
|
||||
layout.addLayout(btn_layout)
|
||||
|
||||
# 预览更新函数
|
||||
def update_preview():
|
||||
selected = preset_combo.currentText()
|
||||
self.update_preset_preview(selected)
|
||||
|
||||
preset_combo.currentTextChanged.connect(update_preview)
|
||||
|
||||
# 存储对话框状态
|
||||
self.current_preview_dialog = dialog
|
||||
self.preview_combo = preset_combo
|
||||
|
||||
# 初始化预览
|
||||
if preset_tasks:
|
||||
update_preview()
|
||||
|
||||
# 显示对话框
|
||||
if dialog.exec() == QDialog.Accepted:
|
||||
selected_task = preset_combo.currentText()
|
||||
self.save_form()
|
||||
new_idx = len(self.tasks)
|
||||
|
||||
# 从配置文件加载预设任务参数
|
||||
config = self.load_preset_task_config(selected_task)
|
||||
if config:
|
||||
new_task = self._make_task_obj({
|
||||
"name": config.get("name", selected_task),
|
||||
"frequency": config.get("frequency", 500),
|
||||
"delay": config.get("delay", 0),
|
||||
"stack": config.get("stack", 256),
|
||||
"description": config.get("description", ""),
|
||||
"freq_control": config.get("freq_control", True)
|
||||
})
|
||||
else:
|
||||
new_task = self._make_task_obj({"name": selected_task})
|
||||
|
||||
new_task["preset_task"] = selected_task
|
||||
|
||||
self.tasks.append(new_task)
|
||||
self.current_index = new_idx
|
||||
self.refresh_task_btns()
|
||||
self.show_task_form(self.tasks[self.current_index])
|
||||
|
||||
InfoBar.success(
|
||||
title="添加成功",
|
||||
content=f"已添加预设任务:{selected_task}",
|
||||
parent=self,
|
||||
duration=2000
|
||||
)
|
||||
|
||||
def update_preset_preview(self, task_name):
|
||||
"""更新预设任务预览信息"""
|
||||
# 从配置加载信息
|
||||
config = self.load_preset_task_config(task_name)
|
||||
if config:
|
||||
self.info_freq.setText(f"频率: {config.get('frequency', 500)} Hz")
|
||||
self.info_delay.setText(f"延时: {config.get('delay', 0)} ms")
|
||||
self.info_stack.setText(f"堆栈: {config.get('stack', 256)} Bytes")
|
||||
freq_ctrl = "启用" if config.get('freq_control', True) else "禁用"
|
||||
self.info_ctrl.setText(f"频率控制: {freq_ctrl}")
|
||||
|
||||
description = config.get('description', f'预设任务:{task_name}')
|
||||
self.preview_desc.setText(description)
|
||||
else:
|
||||
self.info_freq.setText("频率: 500 Hz")
|
||||
self.info_delay.setText("延时: 0 ms")
|
||||
self.info_stack.setText("堆栈: 256 Bytes")
|
||||
self.info_ctrl.setText("频率控制: 启用")
|
||||
self.preview_desc.setText(f"预设任务:{task_name}")
|
||||
|
||||
def on_preset_task_selected(self, task_name):
|
||||
"""预设任务选择事件(向后兼容)"""
|
||||
pass
|
||||
|
||||
def get_preset_task_description(self, task_name):
|
||||
"""获取预设任务的描述信息"""
|
||||
# 首先尝试从 yaml 配置中获取描述
|
||||
config = self.load_preset_task_config(task_name)
|
||||
if config and 'description' in config:
|
||||
return f"预设任务:{task_name}\n\n{config['description']}\n\n频率控制:{'启用' if config.get('freq_control', True) else '禁用'}\n运行频率:{config.get('frequency', 500)} Hz\n堆栈大小:{config.get('stack', 256)} Bytes\n初始延时:{config.get('delay', 0)} ms"
|
||||
|
||||
# 如果没有配置文件,则从代码注释中提取
|
||||
try:
|
||||
task_code = self.load_preset_task_code(task_name)
|
||||
if task_code:
|
||||
# 尝试从注释中提取描述
|
||||
lines = task_code.split('\n')
|
||||
description_lines = []
|
||||
in_comment = False
|
||||
|
||||
for line in lines[:20]: # 只检查前20行
|
||||
line = line.strip()
|
||||
if line.startswith('/*'):
|
||||
in_comment = True
|
||||
if 'Task' in line and line != '/*':
|
||||
description_lines.append(line.replace('/*', '').strip())
|
||||
continue
|
||||
elif line.endswith('*/'):
|
||||
in_comment = False
|
||||
break
|
||||
elif in_comment and line and not line.startswith('*'):
|
||||
description_lines.append(line)
|
||||
|
||||
if description_lines:
|
||||
return '\n'.join(description_lines)
|
||||
else:
|
||||
return f"预设任务:{task_name}\n这是一个预定义的任务模板,包含完整的实现代码。"
|
||||
else:
|
||||
return f"预设任务:{task_name}\n无法读取任务描述。"
|
||||
except Exception as e:
|
||||
return f"预设任务:{task_name}\n读取描述时出现错误:{str(e)}"
|
||||
|
||||
def add_task(self):
|
||||
self.save_form()
|
||||
new_idx = len(self.tasks)
|
||||
@@ -302,5 +578,10 @@ class TaskConfigDialog(QDialog):
|
||||
}
|
||||
if freq_ctrl:
|
||||
task["frequency"] = freq
|
||||
|
||||
# 保留预设任务信息
|
||||
if "preset_task" in t:
|
||||
task["preset_task"] = t["preset_task"]
|
||||
|
||||
tasks.append(task)
|
||||
return tasks
|
||||
Reference in New Issue
Block a user