| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219 |
- 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("<F2>", lambda event: self.more_click("买入/开多(F2)"))
- # self.bind_all("<F3>", lambda event: self.more_click("平仓滑竿(F3)"))
- # self.bind_all("<F4>", lambda event: self.more_click("卖出/平多(F4)"))
- # self.bind_all("<F5>", lambda event: self.more_click("开仓滑竿(F5)"))
- # self.bind_all("<F6>", lambda event: self.more_click("开仓/开空(F6)"))
- # self.bind_all("<F7>", lambda event: self.more_click("平仓滑竿(F7)"))
- # self.bind_all("<F8>", 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 # 缓存内容
|