mirror of
https://github.com/goldenfishs/MRobot.git
synced 2025-09-14 12:54:33 +08:00
150 lines
5.8 KiB
Python
150 lines
5.8 KiB
Python
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QSizePolicy, QTreeWidget, QTreeWidgetItem, QStackedWidget
|
|
from PyQt5.QtCore import Qt
|
|
from qfluentwidgets import TitleLabel, BodyLabel, PushButton
|
|
from app.tools.analyzing_ioc import analyzing_ioc
|
|
from app.code_page.bsp_interface import bsp
|
|
|
|
import os
|
|
import csv
|
|
import importlib
|
|
|
|
class CodeGenerateInterface(QWidget):
|
|
def __init__(self, project_path, parent=None):
|
|
super().__init__(parent)
|
|
self.setObjectName("CodeGenerateInterface")
|
|
self.project_path = project_path
|
|
|
|
self._init_ui()
|
|
|
|
def _init_ui(self):
|
|
"""初始化界面布局"""
|
|
main_layout = QVBoxLayout(self)
|
|
main_layout.setAlignment(Qt.AlignTop)
|
|
main_layout.setContentsMargins(10, 10, 10, 10)
|
|
|
|
top_layout = self._create_top_layout()
|
|
main_layout.addLayout(top_layout)
|
|
|
|
# 下方主区域,左右分栏
|
|
content_layout = QHBoxLayout()
|
|
content_layout.setContentsMargins(0, 10, 0, 0)
|
|
main_layout.addLayout(content_layout)
|
|
|
|
# 左侧树形列表
|
|
self.tree = QTreeWidget()
|
|
self.tree.setHeaderHidden(True)
|
|
self.tree.setMaximumWidth(250)
|
|
content_layout.addWidget(self.tree)
|
|
|
|
# 右侧内容区
|
|
self.stack = QStackedWidget()
|
|
content_layout.addWidget(self.stack)
|
|
|
|
self._load_csv_and_build_tree()
|
|
self.tree.itemClicked.connect(self.on_tree_item_clicked)
|
|
|
|
def _create_top_layout(self):
|
|
"""创建顶部横向布局"""
|
|
top_layout = QHBoxLayout()
|
|
top_layout.setAlignment(Qt.AlignTop)
|
|
|
|
# 项目名称标签
|
|
project_name = os.path.basename(self.project_path)
|
|
name_label = BodyLabel(f"项目名称: {project_name}")
|
|
name_label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
|
|
top_layout.addWidget(name_label)
|
|
|
|
# FreeRTOS状态标签
|
|
freertos_label = BodyLabel(f"FreeRTOS: {self._get_freertos_status()}")
|
|
freertos_label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
|
|
top_layout.addWidget(freertos_label)
|
|
|
|
# 生成代码按钮
|
|
generate_btn = PushButton("Generate Code")
|
|
generate_btn.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
|
|
generate_btn.clicked.connect(self.generate_code)
|
|
top_layout.addWidget(generate_btn, alignment=Qt.AlignRight)
|
|
|
|
return top_layout
|
|
|
|
def generate_code(self):
|
|
"""生成代码逻辑"""
|
|
# 收集所有已加载的页面对象
|
|
pages = []
|
|
for i in range(self.stack.count()):
|
|
widget = self.stack.widget(i)
|
|
pages.append(widget)
|
|
bsp.generate_bsp(self.project_path, pages)
|
|
# component.generate_component(self.project_path)
|
|
# device.generate_device(self.project_path)
|
|
|
|
|
|
def _get_freertos_status(self):
|
|
"""获取FreeRTOS状态"""
|
|
ioc_files = [f for f in os.listdir(self.project_path) if f.endswith('.ioc')]
|
|
if ioc_files:
|
|
ioc_path = os.path.join(self.project_path, ioc_files[0])
|
|
return "开启" if analyzing_ioc.is_freertos_enabled_from_ioc(ioc_path) else "未开启"
|
|
return "未找到.ioc文件"
|
|
|
|
def _load_csv_and_build_tree(self):
|
|
# 获取脚本目录
|
|
script_dir = os.path.dirname(os.path.abspath(__file__))
|
|
csv_path = os.path.join(script_dir, "../assets/User_code/config.csv")
|
|
csv_path = os.path.abspath(csv_path)
|
|
print(f"加载CSV路径: {csv_path}")
|
|
if not os.path.exists(csv_path):
|
|
print(f"配置文件未找到: {csv_path}")
|
|
return
|
|
self.tree.clear()
|
|
with open(csv_path, newline='', encoding='utf-8') as f:
|
|
reader = csv.reader(f)
|
|
for row in reader:
|
|
row = [cell.strip() for cell in row if cell.strip()]
|
|
if not row:
|
|
continue
|
|
main_title = row[0]
|
|
main_item = QTreeWidgetItem([main_title])
|
|
for sub in row[1:]:
|
|
sub_item = QTreeWidgetItem([sub])
|
|
main_item.addChild(sub_item)
|
|
self.tree.addTopLevelItem(main_item)
|
|
self.tree.repaint()
|
|
|
|
def on_tree_item_clicked(self, item, column):
|
|
if item.parent():
|
|
main_title = item.parent().text(0)
|
|
sub_title = item.text(0)
|
|
class_name = f"{main_title}_{sub_title}".replace("-", "_")
|
|
widget = self._get_or_create_page(class_name)
|
|
if widget:
|
|
self.stack.setCurrentWidget(widget)
|
|
|
|
def _get_or_create_page(self, class_name):
|
|
for i in range(self.stack.count()):
|
|
w = self.stack.widget(i)
|
|
if w.objectName() == class_name:
|
|
return w
|
|
try:
|
|
module_name = f"app.code_page.{class_name.split('_')[0]}_interface"
|
|
module = importlib.import_module(module_name)
|
|
cls = getattr(module, class_name)
|
|
widget = cls(self.project_path)
|
|
widget.setObjectName(class_name)
|
|
self.stack.addWidget(widget)
|
|
print(f"加载页面类: {class_name} 来自模块: {module_name}")
|
|
return widget
|
|
except Exception as e:
|
|
# 自动识别通用外设页面
|
|
from app.code_page.bsp_interface import BspSimplePeripheral
|
|
peripheral_name = class_name.split('_')[1] if '_' in class_name else class_name
|
|
# 模板文件名自动推断
|
|
template_names = {
|
|
'header': f"{peripheral_name.lower()}.h",
|
|
'source': f"{peripheral_name.lower()}.c"
|
|
}
|
|
widget = BspSimplePeripheral(self.project_path, peripheral_name, template_names)
|
|
widget.setObjectName(class_name)
|
|
self.stack.addWidget(widget)
|
|
print(f"自动加载通用外设页面: {class_name}")
|
|
return widget |