Sfoglia il codice sorgente

Merge remote-tracking branch 'origin/master'

# Conflicts:
#	README.md
#	main.py
#	plat/base/base_control.py
#	plat/deepcoin_control.py
#	pyproject.toml
#	test/deepcoin/test_deepcoin_control.py
xiao.qiang 6 mesi fa
parent
commit
20c8e5e335
1 ha cambiato i file con 219 aggiunte e 0 eliminazioni
  1. 219 0
      gui/ui.py

+ 219 - 0
gui/ui.py

@@ -0,0 +1,219 @@
+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  # 缓存内容