import tkinter as tk from tkinter import ttk, messagebox, simpledialog from config import config_manager import threading class ConfigGUI: """配置GUI界面""" def __init__(self): self.root = tk.Tk() self.root.title("配置管理 - 火炬之光自动化") self.root.geometry("800x600") self.selected_index = 0 self.setup_ui() self.load_current_config() def setup_ui(self): """设置UI界面""" # 左侧:配置组列表 left_frame = ttk.Frame(self.root, padding="10") left_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=False) ttk.Label(left_frame, text="配置组列表", font=('Arial', 12, 'bold')).pack() # 配置组列表 self.group_listbox = tk.Listbox(left_frame, width=20, height=25) self.group_listbox.pack(fill=tk.BOTH, expand=True, pady=5) self.group_listbox.bind('<>', self.on_group_select) # 按钮 btn_frame = ttk.Frame(left_frame) btn_frame.pack(fill=tk.X) ttk.Button(btn_frame, text="添加组", command=self.add_group).pack(fill=tk.X, pady=2) ttk.Button(btn_frame, text="删除组", command=self.delete_group).pack(fill=tk.X, pady=2) ttk.Button(btn_frame, text="设为活动", command=self.set_active).pack(fill=tk.X, pady=2) # 右侧:配置详情 right_frame = ttk.Frame(self.root, padding="10") right_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True) ttk.Label(right_frame, text="配置详情", font=('Arial', 12, 'bold')).pack() # 配置项 self.config_vars = {} # 基本配置 basic_frame = ttk.LabelFrame(right_frame, text="基本配置", padding="10") basic_frame.pack(fill=tk.X, pady=5) self.create_entry(basic_frame, "name", "配置组名称:") self.create_entry(basic_frame, "camera_index", "采集卡索引:") self.create_entry(basic_frame, "camera_width", "采集宽度:") self.create_entry(basic_frame, "camera_height", "采集高度:") # 串口配置 serial_frame = ttk.LabelFrame(right_frame, text="串口配置", padding="10") serial_frame.pack(fill=tk.X, pady=5) self.create_entry(serial_frame, "serial_port", "串口:") self.create_entry(serial_frame, "serial_baudrate", "波特率:") # 游戏配置 game_frame = ttk.LabelFrame(right_frame, text="游戏配置", padding="10") game_frame.pack(fill=tk.X, pady=5) self.create_entry(game_frame, "move_velocity", "移动速度(v值):") # 预览配置 preview_frame = ttk.LabelFrame(right_frame, text="预览配置", padding="10") preview_frame.pack(fill=tk.X, pady=5) self.create_entry(preview_frame, "preview_width", "预览宽度:", prefix="display") self.create_entry(preview_frame, "preview_height", "预览高度:", prefix="display") self.create_entry(preview_frame, "preview_columns", "预览列数:", prefix="display") self.create_entry(preview_frame, "preview_rows", "预览行数:", prefix="display") # 保存按钮 save_frame = ttk.Frame(right_frame) save_frame.pack(fill=tk.X, pady=10) ttk.Button(save_frame, text="保存配置", command=self.save_config).pack(side=tk.LEFT, padx=5) ttk.Button(save_frame, text="启动预览", command=self.start_preview).pack(side=tk.LEFT, padx=5) ttk.Button(save_frame, text="启动程序", command=self.start_program).pack(side=tk.LEFT, padx=5) def create_entry(self, parent, key, label, prefix=None): """创建输入框""" frame = ttk.Frame(parent) frame.pack(fill=tk.X, pady=3) ttk.Label(frame, text=label, width=15).pack(side=tk.LEFT) var = tk.StringVar() entry = ttk.Entry(frame, textvariable=var, width=25) entry.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=5) # 保存变量引用 if prefix: full_key = f"{prefix}_{key}" else: full_key = key self.config_vars[full_key] = var def load_current_config(self): """加载当前配置到界面""" # 加载配置组列表 self.update_group_list() # 加载预览配置 display = config_manager.config.get('display', {}) for key in ['preview_width', 'preview_height', 'preview_columns', 'preview_rows']: if key in display: self.config_vars[f"display_{key}"].set(str(display[key])) def update_group_list(self): """更新配置组列表""" self.group_listbox.delete(0, tk.END) for i, group in enumerate(config_manager.config['groups']): status = "✓" if group.get('active', False) else " " self.group_listbox.insert(tk.END, f"{status} {group['name']}") def on_group_select(self, event): """选择配置组""" selection = self.group_listbox.curselection() if selection: self.selected_index = selection[0] self.load_group_config(self.selected_index) def load_group_config(self, index): """加载配置组详情""" group = config_manager.get_group_by_index(index) if group: for key, var in self.config_vars.items(): if not key.startswith('display_'): if key in group: var.set(str(group[key])) def add_group(self): """添加配置组""" name = simpledialog.askstring("添加配置组", "请输入配置组名称:", initialvalue=f"配置组{len(config_manager.config['groups'])+1}") if name: config_manager.add_group(name) self.update_group_list() messagebox.showinfo("成功", f"已添加配置组: {name}") def delete_group(self): """删除配置组""" selection = self.group_listbox.curselection() if not selection: messagebox.showwarning("警告", "请先选择要删除的配置组") return if messagebox.askyesno("确认", "确定要删除选中的配置组吗?"): config_manager.delete_group(selection[0]) self.update_group_list() messagebox.showinfo("成功", "配置组已删除") def set_active(self): """设置为活动配置组""" selection = self.group_listbox.curselection() if not selection: messagebox.showwarning("警告", "请先选择要设为活动的配置组") return config_manager.set_active_group(selection[0]) self.update_group_list() messagebox.showinfo("成功", "已设置为活动配置组") def save_config(self): """保存当前编辑的配置""" # 保存当前组的配置 group = config_manager.get_group_by_index(self.selected_index) if group: for key, var in self.config_vars.items(): if not key.startswith('display_'): try: value = int(var.get()) if var.get().isdigit() else var.get() group[key] = value except: group[key] = var.get() # 保存预览配置 display = config_manager.config.get('display', {}) for key in ['preview_width', 'preview_height', 'preview_columns', 'preview_rows']: var = self.config_vars.get(f"display_{key}") if var: try: display[key] = int(var.get()) except: pass config_manager.config['display'] = display if config_manager.save_config(): messagebox.showinfo("成功", "配置已保存") else: messagebox.showerror("错误", "配置保存失败") def start_preview(self): """启动预览窗口""" # 保存配置 self.save_config() # 启动预览窗口 from preview import PreviewWindow preview_thread = threading.Thread(target=lambda: PreviewWindow().run()) preview_thread.daemon = True preview_thread.start() def start_program(self): """启动主程序""" # 保存配置 self.save_config() messagebox.showinfo("提示", "配置已保存,请运行主程序") def run(self): """运行GUI""" self.root.mainloop() if __name__ == "__main__": app = ConfigGUI() app.run()