import logging import tempfile import tkinter as tk from tkinter import Menu, Text, Label, Entry, Button from typing import List from PIL import Image, ImageTk # 需要安装 Pillow 库 from plat.base.base_control import AbsControl keys_mapping = { "F1": "开仓滑竿", "F2": "买入/开多", "F3": "平仓滑竿", "F4": "卖出/平多", "F5": "开仓滑竿", "F6": "开仓/开空", "F7": "平仓滑竿", "F8": "卖出/平空" } class Application(tk.Tk): """ 页面布局 """ def __init__(self, controls=None): super().__init__() if controls is None: controls = [] self._controls: List[AbsControl] = controls # 控件 self.content_frame = None self.navigation_buttons = None self.navigation_frame = None self.title("群控小助手") self.geometry("1366x768") self.create_menu() self.create_navigation() self.create_content_area() self._event_build() self._content_cache = {} # 缓存内容 # =========================== # adb 连接 # self.adb_serial = tk.StringVar() def create_menu(self): menubar = Menu(self) self.config(menu=menubar) menu1 = Menu(menubar, tearoff=0) menu1.add_command(label="配置", command=lambda: self.more_click("配置")) menu1.add_command(label="退出", command=self.quit) menubar.add_cascade(label="管理", menu=menu1) menu2 = Menu(menubar, tearoff=0) def _bind_command(key, label): menu2.add_command(label=label, accelerator=key, command=lambda k=key, v=label: self.more_click(k, v)) # 循环 keys_mapping 字典 ,生成菜单 for key, value in keys_mapping.items(): label = f"{value}({key})" logging.info(f"生成菜单项:{label}") _bind_command(key, label) # key = "F1" # label = f"开仓滑竿({key})" # menu2.add_command(label=label, accelerator=key, command=lambda: self.more_click(key, label)) # key = "F2" # label = f"买入/开多({key})" # menu2.add_command(label=label, accelerator=key, command=lambda: self.more_click(key, label)) # key = "F3" # label = f"平仓滑竿({key})" # menu2.add_command(label=label, accelerator=key, command=lambda: self.more_click(key, label)) # key = "F4" # label = f"卖出/平多({key})" # menu2.add_command(label=label, accelerator=key, command=lambda: self.more_click(key, label)) # key = "F5" # label = f"开仓滑竿({key})" # menu2.add_command(label=label, accelerator=key, command=lambda: self.more_click(key, label)) # key = "F6" # label = f"开仓/开空({key})" # menu2.add_command(label=label, accelerator=key, command=lambda: self.more_click(key, label)) # key = "F7" # label = f"平仓滑竿({key})" # menu2.add_command(label=label, accelerator=key, command=lambda: self.more_click(key, label)) # key = "F8" # label = f"卖出/平空({key})" # menu2.add_command(label=label, accelerator=key, command=lambda: self.more_click(key, label)) menubar.add_cascade(label="操作", menu=menu2) menu1 = Menu(menubar, tearoff=0) menu1.add_command(label="关于", command=lambda: self.more_click('', "关于")) menubar.add_cascade(label="帮助", menu=menu1) # 多点击事件,循环调用 def more_click(self, key, msg): print(msg) for item in self._controls: item.print_log(msg) met_name = f'event_{key.lower()}' if hasattr(item, met_name): evt = getattr(item, met_name) evt() else: print(f"实例 {item.name}没有名为 '{key}' 的方法") def add_control(self, control: AbsControl): self._controls.append(control) def _event_build(self): def _bind_command(key, label): self.bind_all(f"<{key}>", lambda event: self.more_click(key, label)) for key, value in keys_mapping.items(): label = f"{value}({key})" logging.info(f'绑定事件:{label}') _bind_command(key, label) # self.bind_all("", lambda event: self.more_click("买入/开多(F2)")) # self.bind_all("", lambda event: self.more_click("平仓滑竿(F3)")) # self.bind_all("", lambda event: self.more_click("卖出/平多(F4)")) # self.bind_all("", lambda event: self.more_click("开仓滑竿(F5)")) # self.bind_all("", lambda event: self.more_click("开仓/开空(F6)")) # self.bind_all("", lambda event: self.more_click("平仓滑竿(F7)")) # self.bind_all("", lambda event: self.more_click("卖出/平空(F8)")) def create_navigation(self): self.navigation_frame = tk.Frame(self, width=150, bg="#f0f0f0") self.navigation_frame.pack(side=tk.LEFT, fill=tk.Y) for item in self._controls: # image = Image.open(item['logo']) # photo = ImageTk.PhotoImage(image) button = tk.Button(self.navigation_frame, text=item.name, command=lambda i=item: self.show_content(i), compound=tk.LEFT) button.pack(fill=tk.X, pady=5) # self.navigation_buttons.append(button) def test_connect(self, control: AbsControl, serial: str, img: Label = None): logging.info(f"测试连接:{serial}") control.connect_adb(serial) self.flush_screenshot(control, img) def flush_screenshot(self, control: AbsControl, image_label: Label): """ 刷新截图 """ control.screenshot() try: tmp = tempfile.gettempdir() image = Image.open(f"{tmp}/{control.name}.png") w = 380 image = image.resize((w, w * 16 // 9)) logging.info(f"刷新截图:{image}") photo = ImageTk.PhotoImage(image) image_label.config(image=photo) image_label.image = photo # 保持对图片的引用 except FileNotFoundError: logging.error(f"图片不存在") pass def create_content_area(self): self.content_frame = tk.Frame(self) self.content_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True) def show_content(self, item: AbsControl): print(f"---> {item.name},{self._content_cache}") for key, value in self._content_cache.items(): if key != item.name: value.pack_forget() if item.name in self._content_cache: content = self._content_cache[item.name] content.pack(fill=tk.BOTH, expand=True) else: content = tk.Frame(self.content_frame) content.pack(fill=tk.BOTH, expand=True) # 表单区域 form_frame = tk.Frame(content) form_frame.pack(side=tk.TOP, fill=tk.X) # 设置第二列的权重 # form_frame.columnconfigure(1, weight=1) tk.Label(form_frame, text="连接:").grid(row=0, column=0, sticky="w") name_entry = Entry(form_frame, width=100) name_entry.grid(row=0, column=1) name_entry.insert(0, '127.0.0.1:6555') # 图片预览区域 image_label = Label(content, width=200, height=380) Button(form_frame, text="测试连接", command=lambda n=name_entry: self.test_connect(item, name_entry.get(), image_label)).grid(row=0, column=1, sticky="e") Button(form_frame, text="查看手机", command=lambda n=name_entry: self.flush_screenshot(item, image_label)).grid(row=0, column=2, sticky="e") # tk.Label(form_frame, text="年龄:").grid(row=1, column=0, sticky="w") # age_entry = Entry(form_frame) # age_entry.grid(row=1, column=1) # # Button(form_frame, text="保存").grid(row=2, column=1, sticky="e") # 日志区域 log_text = Text(content, height=10) log_text.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) log_text.insert(tk.END, f"导航 {item} 被点击\n") item.set_log_func(lambda msg: log_text.insert(tk.END, f"{msg}\n")) image_label.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True) # self.flush_screenshot(image_label) self._content_cache[item.name] = content # 缓存内容