mirror of
				https://github.com/goldenfishs/MRobot.git
				synced 2025-10-31 07:05: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