import logging import tempfile import tkinter as tk from tkinter import Menu, Text, Label, Entry, Button, ttk from typing import Dict from PIL import Image, ImageTk # 需要安装 Pillow 库 from control.base.base_control import AbsControl, BaseControl from control.ui.settings_control import SettingsControl from gui.phone_list import PhoneListUI from gui.settings import SettingUI from utils.config import version from utils.control_util import ControlUtils CACHE_KEY_SETTING = 'settings' CACHE_KEY_PHONE_LIST = 'phone_list' keys_mapping = { "F1": "开仓滑竿", "F2": "买入/开多", "F3": "平仓滑竿", "F4": "卖出/平多", "F5": "开仓滑竿", "F6": "开仓/开空", "F7": "平仓滑竿", "F8": "卖出/平空" } class Application(tk.Tk): """ 页面布局 """ def __init__(self, controls=None): super().__init__() self.notebook = None if controls is None: controls = {} self._controls: Dict[str, AbsControl] = controls # 控件 # self.content_frame = None self.navigation_buttons = None self.navigation_frame = None self.title(f"群控小助手[{version}]") self.geometry("1366x768") self.create_menu() # self.create_navigation() self.create_content_area() # self._event_build() self._content_cache = {} # 缓存内容 def create_menu(self): menubar = Menu(self) self.config(menu=menubar) menu1 = Menu(menubar, tearoff=0) menu1.add_command(label="设置(S)", command=lambda: self.click_settings()) menu1.add_command(label="手机(T)", command=lambda: self.click_phone_list()) menu1.add_command(label="退出(Q)", command=self.quit) menubar.add_cascade(label="视图", menu=menu1) menu1 = Menu(menubar, tearoff=0) menu1.add_command(label="关于", command=lambda: self.more_click('', "关于")) menubar.add_cascade(label="帮助", menu=menu1) def create_content_area(self): # """创建主内容区域""" # self.content_frame = tk.Frame(self) # self.content_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) # 创建一个 Style 实例 style = ttk.Style() notebook_style_name = "main_ui.TNotebook" style.configure(notebook_style_name) # 可以进行其他配置,如果需要 style.layout(notebook_style_name + ".Tab", []) self.notebook = ttk.Notebook(self, style=notebook_style_name) # 将自定义样式应用到这个 Notebook self.notebook.pack(fill="both", expand=True) def _toggle_content(self, name: str): """根据标签文本选择 Notebook 中的选项卡。""" logging.info(f"打开页面 '{name}' 。") for index in range(self.notebook.index("end")): if self.notebook.tab(index, "text") == name: self.notebook.select(index) return True return False def click_settings(self): """显示设置界面""" # has = CACHE_KEY_SETTING in self._content_cache logging.info(f"点击了设置:{SettingUI.__name__}") # # # 创建或获取UI if not self._toggle_content(SettingUI.__name__): ui = SettingUI(control=self._controls[SettingsControl.__name__]) self.notebook.add(ui, text=SettingUI.__name__) self._toggle_content(SettingUI.__name__) def click_phone_list(self): """ 显示手机列表 """ logging.info(f"点击了设置,缓存命中:{PhoneListUI.__name__}") # 清空其他所有内容 if not self._toggle_content(PhoneListUI.__name__): ui = PhoneListUI(control=ControlUtils(**{'top':self})) self.notebook.add(ui, text=PhoneListUI.__name__) self._toggle_content(PhoneListUI.__name__) # 多点击事件,循环调用 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) # 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) # logging.info(f"导航按钮:{item.name}->{item.ctx}") # button = tk.Button(self.navigation_frame, text=item.name, command=lambda i=item: # self.init_connect_content(i) if i.ctx == 1 else \ # self.plat_content(i) # # if item.ctx == 1 else self.plat_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}") # # if serial.startswith("adb connect"): # serial = serial.split('connect')[1].strip() # # 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") logging.info(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 plat_content(self, item: AbsControl): # print(f"plat_content---> {item.name},{self._content_cache}") # for key, value in self._content_cache.items(): # if key != item.name: # value.pack_forget() # # content: tk.Frame # # if item.name in self._content_cache: # content = self._content_cache[item.name] # else: # content = tk.Frame(self.content_frame) # # 表单区域 # 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) # info = BaseControl.connect_dict[item.get_app_package_name()] # name_entry.insert(0, info['device']) # # 图片预览区域 # 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") # # # 日志区域 # log_text = Text(content, height=10) # log_text.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) # log_text.insert(tk.END, f"导航 {item.name} 被点击\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 # 缓存内容 # # content.pack(fill=tk.BOTH, expand=True)