mirror of
				https://github.com/goldenfishs/MRobot.git
				synced 2025-10-31 15:15:43 +08:00 
			
		
		
		
	可以复制模组了
This commit is contained in:
		
							parent
							
								
									3f477172f2
								
							
						
					
					
						commit
						22b7d1416a
					
				
							
								
								
									
										281
									
								
								MRobot.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										281
									
								
								MRobot.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,281 @@ | |||||||
|  | import tkinter as tk | ||||||
|  | import os | ||||||
|  | import threading | ||||||
|  | import shutil | ||||||
|  | import re | ||||||
|  | from git import Repo | ||||||
|  | 
 | ||||||
|  | # 配置常量 | ||||||
|  | REPO_DIR = "MRobot_repo" | ||||||
|  | REPO_URL = "http://gitea.qutrobot.top/robofish/MRobot.git" | ||||||
|  | 
 | ||||||
|  | class MRobotApp: | ||||||
|  |     def __init__(self): | ||||||
|  |         self.ioc_data = None | ||||||
|  |         self.add_gitignore_var = None  # 延迟初始化 | ||||||
|  |         self.header_file_vars = {} | ||||||
|  | 
 | ||||||
|  |     # 克隆仓库 | ||||||
|  |     def clone_repo(self): | ||||||
|  |         try: | ||||||
|  |             if os.path.exists(REPO_DIR): | ||||||
|  |                 shutil.rmtree(REPO_DIR) | ||||||
|  |             print(f"正在克隆仓库到 {REPO_DIR}...") | ||||||
|  |             Repo.clone_from(REPO_URL, REPO_DIR) | ||||||
|  |             print("仓库克隆成功!") | ||||||
|  |         except Exception as e: | ||||||
|  |             print(f"克隆仓库时出错: {e}") | ||||||
|  | 
 | ||||||
|  |     # 删除克隆的仓库 | ||||||
|  |     def delete_repo(self): | ||||||
|  |         try: | ||||||
|  |             if os.path.exists(REPO_DIR): | ||||||
|  |                 shutil.rmtree(REPO_DIR) | ||||||
|  |                 print(f"已删除克隆的仓库目录: {REPO_DIR}") | ||||||
|  |         except Exception as e: | ||||||
|  |             print(f"删除仓库目录时出错: {e}") | ||||||
|  | 
 | ||||||
|  |     # 复制文件 | ||||||
|  |     def copy_file_from_repo(self, src_path, dest_path): | ||||||
|  |         try: | ||||||
|  |             # 修复路径拼接问题,确保 src_path 不重复包含 REPO_DIR | ||||||
|  |             if src_path.startswith(REPO_DIR): | ||||||
|  |                 full_src_path = src_path | ||||||
|  |             else: | ||||||
|  |                 full_src_path = os.path.join(REPO_DIR, src_path.lstrip(os.sep)) | ||||||
|  | 
 | ||||||
|  |             # 检查源文件是否存在 | ||||||
|  |             if not os.path.exists(full_src_path): | ||||||
|  |                 print(f"文件 {full_src_path} 不存在!(检查路径或仓库内容)") | ||||||
|  |                 return | ||||||
|  | 
 | ||||||
|  |             # 检查目标路径是否有效 | ||||||
|  |             if not dest_path or not dest_path.strip(): | ||||||
|  |                 print("目标路径为空或无效,无法复制文件!") | ||||||
|  |                 return | ||||||
|  | 
 | ||||||
|  |             # 创建目标目录(如果不存在) | ||||||
|  |             dest_dir = os.path.dirname(dest_path) | ||||||
|  |             if dest_dir and not os.path.exists(dest_dir): | ||||||
|  |                 os.makedirs(dest_dir, exist_ok=True) | ||||||
|  | 
 | ||||||
|  |             # 执行文件复制 | ||||||
|  |             shutil.copy(full_src_path, dest_path) | ||||||
|  |             print(f"文件已从 {full_src_path} 复制到 {dest_path}") | ||||||
|  |         except Exception as e: | ||||||
|  |             print(f"复制文件时出错: {e}") | ||||||
|  | 
 | ||||||
|  |     # 查找并读取 .ioc 文件 | ||||||
|  |     def find_and_read_ioc_file(self): | ||||||
|  |         try: | ||||||
|  |             for file in os.listdir("."): | ||||||
|  |                 if file.endswith(".ioc"): | ||||||
|  |                     print(f"找到 .ioc 文件: {file}") | ||||||
|  |                     with open(file, "r", encoding="utf-8") as f: | ||||||
|  |                         return f.read() | ||||||
|  |             print("未找到 .ioc 文件!") | ||||||
|  |         except Exception as e: | ||||||
|  |             print(f"读取 .ioc 文件时出错: {e}") | ||||||
|  |         return None | ||||||
|  | 
 | ||||||
|  |     # 检查是否启用了 FreeRTOS | ||||||
|  |     def check_freertos_enabled(self, ioc_data): | ||||||
|  |         try: | ||||||
|  |             return bool(re.search(r"Mcu\.IP\d+=FREERTOS", ioc_data)) | ||||||
|  |         except Exception as e: | ||||||
|  |             print(f"检查 FreeRTOS 配置时出错: {e}") | ||||||
|  |             return False | ||||||
|  | 
 | ||||||
|  |     # 生成操作 | ||||||
|  |     def generate_action(self): | ||||||
|  |         def task(): | ||||||
|  |             # 检查并创建目录 | ||||||
|  |             self.create_directories() | ||||||
|  |      | ||||||
|  |             if self.add_gitignore_var.get(): | ||||||
|  |                 self.copy_file_from_repo(".gitignore", ".gitignore") | ||||||
|  |             if self.ioc_data and self.check_freertos_enabled(self.ioc_data): | ||||||
|  |                 self.copy_file_from_repo("src/freertos.c", os.path.join("Core", "Src", "freertos.c")) | ||||||
|  |      | ||||||
|  |             # 定义需要处理的文件夹 | ||||||
|  |             folders = ["bsp", "component", "device", "module"] | ||||||
|  |      | ||||||
|  |             for folder in folders: | ||||||
|  |                 folder_dir = os.path.join(REPO_DIR, "User", folder) | ||||||
|  |                 for file_name, var in self.header_file_vars.items(): | ||||||
|  |                     if var.get(): | ||||||
|  |                         # 复制 .h 文件 | ||||||
|  |                         h_file_src = os.path.join(folder_dir, f"{file_name}.h") | ||||||
|  |                         h_file_dest = os.path.join("User", folder, f"{file_name}.h") | ||||||
|  |                         self.copy_file_from_repo(h_file_src, h_file_dest) | ||||||
|  |      | ||||||
|  |                         # 复制同名 .c 文件(如果存在) | ||||||
|  |                         c_file_src = os.path.join(folder_dir, f"{file_name}.c") | ||||||
|  |                         c_file_dest = os.path.join("User", folder, f"{file_name}.c") | ||||||
|  |                         if os.path.exists(c_file_src): | ||||||
|  |                             self.copy_file_from_repo(c_file_src, c_file_dest) | ||||||
|  |      | ||||||
|  |         threading.Thread(target=task).start() | ||||||
|  | 
 | ||||||
|  |     # 创建必要的目录 | ||||||
|  |     def create_directories(self): | ||||||
|  |         try: | ||||||
|  |             directories = [ | ||||||
|  |                 "User/bsp", | ||||||
|  |                 "User/component", | ||||||
|  |                 "User/device", | ||||||
|  |                 "User/module", | ||||||
|  |             ] | ||||||
|  |             # 根据是否启用 FreeRTOS 决定是否创建 User/task | ||||||
|  |             if self.ioc_data and self.check_freertos_enabled(self.ioc_data): | ||||||
|  |                 directories.append("User/task") | ||||||
|  | 
 | ||||||
|  |             for directory in directories: | ||||||
|  |                 if not os.path.exists(directory): | ||||||
|  |                     os.makedirs(directory, exist_ok=True) | ||||||
|  |                     print(f"已创建目录: {directory}") | ||||||
|  |                 else: | ||||||
|  |                     print(f"目录已存在: {directory}") | ||||||
|  |         except Exception as e: | ||||||
|  |             print(f"创建目录时出错: {e}") | ||||||
|  | 
 | ||||||
|  |     # 更新 FreeRTOS 状态标签 | ||||||
|  |     def update_freertos_status(self, label): | ||||||
|  |         if self.ioc_data: | ||||||
|  |             status = "已启用" if self.check_freertos_enabled(self.ioc_data) else "未启用" | ||||||
|  |         else: | ||||||
|  |             status = "未检测到 .ioc 文件" | ||||||
|  |         label.config(text=f"FreeRTOS 状态: {status}") | ||||||
|  | 
 | ||||||
|  |     # 初始化 | ||||||
|  |     def initialize(self): | ||||||
|  |         print("初始化中,正在克隆仓库...") | ||||||
|  |         self.clone_repo() | ||||||
|  |         self.ioc_data = self.find_and_read_ioc_file() | ||||||
|  |         print("初始化完成,启动主窗口...") | ||||||
|  |         self.show_main_window() | ||||||
|  | 
 | ||||||
|  |     # 显示主窗口 | ||||||
|  |     def show_main_window(self): | ||||||
|  |         root = tk.Tk() | ||||||
|  |         root.title("MRobot自动生成脚本") | ||||||
|  |         root.geometry("700x700")  # 调整窗口大小 | ||||||
|  |      | ||||||
|  |         # 初始化 BooleanVar | ||||||
|  |         self.add_gitignore_var = tk.BooleanVar(value=True) | ||||||
|  |      | ||||||
|  |         # 添加标题 | ||||||
|  |         title_label = tk.Label(root, text="MRobot 自动生成脚本", font=("Arial", 16, "bold")) | ||||||
|  |         title_label.pack(pady=10) | ||||||
|  |      | ||||||
|  |         # 添加复选框 | ||||||
|  |         gitignore_frame = tk.Frame(root) | ||||||
|  |         gitignore_frame.pack(pady=10) | ||||||
|  |         tk.Checkbutton(gitignore_frame, text="添加 .gitignore", variable=self.add_gitignore_var).pack(anchor="w") | ||||||
|  |      | ||||||
|  |         # 添加 FreeRTOS 状态标签 | ||||||
|  |         freertos_status_label = tk.Label(root, text="FreeRTOS 状态: 检测中...", font=("Arial", 12)) | ||||||
|  |         freertos_status_label.pack(pady=10) | ||||||
|  |         self.update_freertos_status(freertos_status_label) | ||||||
|  |      | ||||||
|  |         # 显示 .h 文件复选框 | ||||||
|  |         header_files_frame = tk.LabelFrame(root, text="模块文件选择", padx=10, pady=10, font=("Arial", 10, "bold")) | ||||||
|  |         header_files_frame.pack(pady=10, fill="both", expand=True) | ||||||
|  |         self.header_files_frame = header_files_frame | ||||||
|  |         self.update_header_files() | ||||||
|  |      | ||||||
|  |         # 添加生成按钮 | ||||||
|  |         button_frame = tk.Frame(root) | ||||||
|  |         button_frame.pack(pady=20) | ||||||
|  |         generate_button = tk.Button(button_frame, text="一键自动生成MR架构", command=self.generate_action, bg="green", fg="white", font=("Arial", 12, "bold")) | ||||||
|  |         generate_button.pack() | ||||||
|  |      | ||||||
|  |         # 在程序关闭时清理 | ||||||
|  |         root.protocol("WM_DELETE_WINDOW", lambda: self.on_closing(root)) | ||||||
|  |         root.mainloop() | ||||||
|  | 
 | ||||||
|  |     # 更新文件夹显示 | ||||||
|  |     def update_folder_display(self): | ||||||
|  |         for widget in self.folder_frame.winfo_children(): | ||||||
|  |             widget.destroy() | ||||||
|  |      | ||||||
|  |         folders = ["User/bsp", "User/component", "User/device", "User/module"] | ||||||
|  |         # if self.ioc_data and self.check_freertos_enabled(self.ioc_data): | ||||||
|  |         #     folders.append("User/task") | ||||||
|  |      | ||||||
|  |         for folder in folders: | ||||||
|  |             # 去掉 "User/" 前缀 | ||||||
|  |             display_name = folder.replace("User/", "") | ||||||
|  |             tk.Label(self.folder_frame, text=display_name).pack() | ||||||
|  | 
 | ||||||
|  |     # 更新 .h 文件复选框 | ||||||
|  |     def update_header_files(self): | ||||||
|  |         for widget in self.header_files_frame.winfo_children(): | ||||||
|  |             widget.destroy() | ||||||
|  | 
 | ||||||
|  |         # 定义需要处理的文件夹 | ||||||
|  |         folders = ["bsp", "component", "device", "module"] | ||||||
|  | 
 | ||||||
|  |         for folder in folders: | ||||||
|  |             folder_dir = os.path.join(REPO_DIR, "User", folder) | ||||||
|  |             if os.path.exists(folder_dir): | ||||||
|  |                 # 创建每个模块的分组框 | ||||||
|  |                 module_frame = tk.LabelFrame(self.header_files_frame, text=folder.capitalize(), padx=10, pady=10, font=("Arial", 10, "bold")) | ||||||
|  |                 module_frame.pack(fill="x", pady=5) | ||||||
|  | 
 | ||||||
|  |                 # 创建一个横向布局的容器 | ||||||
|  |                 row_frame = tk.Frame(module_frame) | ||||||
|  |                 row_frame.pack(fill="x", pady=5) | ||||||
|  | 
 | ||||||
|  |                 for file in os.listdir(folder_dir): | ||||||
|  |                     if file.endswith(".h"): | ||||||
|  |                         file_name_without_extension = os.path.splitext(file)[0]  # 去掉 .h 后缀 | ||||||
|  |                         var = tk.BooleanVar(value=False) | ||||||
|  |                         self.header_file_vars[file_name_without_extension] = var | ||||||
|  |                         # 显示复选框,横向排列 | ||||||
|  |                         tk.Checkbutton( | ||||||
|  |                             row_frame, | ||||||
|  |                             text=file_name_without_extension, | ||||||
|  |                             variable=var | ||||||
|  |                         ).pack(side="left", padx=5, pady=5) | ||||||
|  |     # 生成操作 | ||||||
|  |     def generate_action(self): | ||||||
|  |         def task(): | ||||||
|  |             # 检查并创建目录 | ||||||
|  |             self.create_directories() | ||||||
|  |      | ||||||
|  |             if self.add_gitignore_var.get(): | ||||||
|  |                 self.copy_file_from_repo(".gitignore", ".gitignore") | ||||||
|  |             if self.ioc_data and self.check_freertos_enabled(self.ioc_data): | ||||||
|  |                 self.copy_file_from_repo("src/freertos.c", os.path.join("Core", "Src", "freertos.c")) | ||||||
|  |      | ||||||
|  |             # 定义需要处理的文件夹 | ||||||
|  |             folders = ["bsp", "component", "device", "module"] | ||||||
|  |      | ||||||
|  |             # 遍历每个文件夹,复制选中的 .h 和 .c 文件 | ||||||
|  |             for folder in folders: | ||||||
|  |                 folder_dir = os.path.join(REPO_DIR, "User", folder) | ||||||
|  |                 if not os.path.exists(folder_dir): | ||||||
|  |                     continue  # 如果文件夹不存在,跳过 | ||||||
|  |      | ||||||
|  |                 for file_name in os.listdir(folder_dir): | ||||||
|  |                     file_base, file_ext = os.path.splitext(file_name) | ||||||
|  |                     if file_ext not in [".h", ".c"]: | ||||||
|  |                         continue  # 只处理 .h 和 .c 文件 | ||||||
|  |      | ||||||
|  |                     # 检查是否选中了对应的文件 | ||||||
|  |                     if file_base in self.header_file_vars and self.header_file_vars[file_base].get(): | ||||||
|  |                         src_path = os.path.join(folder_dir, file_name) | ||||||
|  |                         dest_path = os.path.join("User", folder, file_name) | ||||||
|  |                         self.copy_file_from_repo(src_path, dest_path) | ||||||
|  |      | ||||||
|  |         threading.Thread(target=task).start() | ||||||
|  |     # 程序关闭时清理 | ||||||
|  |     def on_closing(self, root): | ||||||
|  |         self.delete_repo() | ||||||
|  |         root.destroy() | ||||||
|  | 
 | ||||||
|  | # 程序入口 | ||||||
|  | if __name__ == "__main__": | ||||||
|  |     app = MRobotApp() | ||||||
|  |     app.initialize() | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 RB
						RB