1
0

ui.py 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. import logging
  2. import tempfile
  3. import tkinter as tk
  4. from tkinter import Menu, Text, Label, Entry, Button
  5. from typing import List
  6. from PIL import Image, ImageTk # 需要安装 Pillow 库
  7. from plat.base.base_control import AbsControl
  8. keys_mapping = {
  9. "F1": "开仓滑竿",
  10. "F2": "买入/开多",
  11. "F3": "平仓滑竿",
  12. "F4": "卖出/平多",
  13. "F5": "开仓滑竿",
  14. "F6": "开仓/开空",
  15. "F7": "平仓滑竿",
  16. "F8": "卖出/平空"
  17. }
  18. class Application(tk.Tk):
  19. """
  20. 页面布局
  21. """
  22. def __init__(self, controls=None):
  23. super().__init__()
  24. if controls is None:
  25. controls = []
  26. self._controls: List[AbsControl] = controls # 控件
  27. self.content_frame = None
  28. self.navigation_buttons = None
  29. self.navigation_frame = None
  30. self.title("群控小助手")
  31. self.geometry("1366x768")
  32. self.create_menu()
  33. self.create_navigation()
  34. self.create_content_area()
  35. self._event_build()
  36. self._content_cache = {} # 缓存内容
  37. # ===========================
  38. # adb 连接
  39. # self.adb_serial = tk.StringVar()
  40. def create_menu(self):
  41. menubar = Menu(self)
  42. self.config(menu=menubar)
  43. menu1 = Menu(menubar, tearoff=0)
  44. menu1.add_command(label="配置", command=lambda: self.more_click("配置"))
  45. menu1.add_command(label="退出", command=self.quit)
  46. menubar.add_cascade(label="管理", menu=menu1)
  47. menu2 = Menu(menubar, tearoff=0)
  48. def _bind_command(key, label):
  49. menu2.add_command(label=label, accelerator=key, command=lambda k=key, v=label: self.more_click(k, v))
  50. # 循环 keys_mapping 字典 ,生成菜单
  51. for key, value in keys_mapping.items():
  52. label = f"{value}({key})"
  53. logging.info(f"生成菜单项:{label}")
  54. _bind_command(key, label)
  55. # key = "F1"
  56. # label = f"开仓滑竿({key})"
  57. # menu2.add_command(label=label, accelerator=key, command=lambda: self.more_click(key, label))
  58. # key = "F2"
  59. # label = f"买入/开多({key})"
  60. # menu2.add_command(label=label, accelerator=key, command=lambda: self.more_click(key, label))
  61. # key = "F3"
  62. # label = f"平仓滑竿({key})"
  63. # menu2.add_command(label=label, accelerator=key, command=lambda: self.more_click(key, label))
  64. # key = "F4"
  65. # label = f"卖出/平多({key})"
  66. # menu2.add_command(label=label, accelerator=key, command=lambda: self.more_click(key, label))
  67. # key = "F5"
  68. # label = f"开仓滑竿({key})"
  69. # menu2.add_command(label=label, accelerator=key, command=lambda: self.more_click(key, label))
  70. # key = "F6"
  71. # label = f"开仓/开空({key})"
  72. # menu2.add_command(label=label, accelerator=key, command=lambda: self.more_click(key, label))
  73. # key = "F7"
  74. # label = f"平仓滑竿({key})"
  75. # menu2.add_command(label=label, accelerator=key, command=lambda: self.more_click(key, label))
  76. # key = "F8"
  77. # label = f"卖出/平空({key})"
  78. # menu2.add_command(label=label, accelerator=key, command=lambda: self.more_click(key, label))
  79. menubar.add_cascade(label="操作", menu=menu2)
  80. menu1 = Menu(menubar, tearoff=0)
  81. menu1.add_command(label="关于", command=lambda: self.more_click('', "关于"))
  82. menubar.add_cascade(label="帮助", menu=menu1)
  83. # 多点击事件,循环调用
  84. def more_click(self, key, msg):
  85. print(msg)
  86. for item in self._controls:
  87. item.print_log(msg)
  88. met_name = f'event_{key.lower()}'
  89. if hasattr(item, met_name):
  90. evt = getattr(item, met_name)
  91. evt()
  92. else:
  93. print(f"实例 {item.name}没有名为 '{key}' 的方法")
  94. def add_control(self, control: AbsControl):
  95. self._controls.append(control)
  96. def _event_build(self):
  97. def _bind_command(key, label):
  98. self.bind_all(f"<{key}>", lambda event: self.more_click(key, label))
  99. for key, value in keys_mapping.items():
  100. label = f"{value}({key})"
  101. logging.info(f'绑定事件:{label}')
  102. _bind_command(key, label)
  103. # self.bind_all("<F2>", lambda event: self.more_click("买入/开多(F2)"))
  104. # self.bind_all("<F3>", lambda event: self.more_click("平仓滑竿(F3)"))
  105. # self.bind_all("<F4>", lambda event: self.more_click("卖出/平多(F4)"))
  106. # self.bind_all("<F5>", lambda event: self.more_click("开仓滑竿(F5)"))
  107. # self.bind_all("<F6>", lambda event: self.more_click("开仓/开空(F6)"))
  108. # self.bind_all("<F7>", lambda event: self.more_click("平仓滑竿(F7)"))
  109. # self.bind_all("<F8>", lambda event: self.more_click("卖出/平空(F8)"))
  110. def create_navigation(self):
  111. self.navigation_frame = tk.Frame(self, width=150, bg="#f0f0f0")
  112. self.navigation_frame.pack(side=tk.LEFT, fill=tk.Y)
  113. for item in self._controls:
  114. # image = Image.open(item['logo'])
  115. # photo = ImageTk.PhotoImage(image)
  116. button = tk.Button(self.navigation_frame, text=item.name, command=lambda i=item: self.show_content(i), compound=tk.LEFT)
  117. button.pack(fill=tk.X, pady=5)
  118. # self.navigation_buttons.append(button)
  119. def test_connect(self, control: AbsControl, serial: str, img: Label = None):
  120. logging.info(f"测试连接:{serial}")
  121. control.connect_adb(serial)
  122. self.flush_screenshot(control, img)
  123. def flush_screenshot(self, control: AbsControl, image_label: Label):
  124. """
  125. 刷新截图
  126. """
  127. control.screenshot()
  128. try:
  129. tmp = tempfile.gettempdir()
  130. image = Image.open(f"{tmp}/{control.name}.png")
  131. w = 380
  132. image = image.resize((w, w * 16 // 9))
  133. logging.info(f"刷新截图:{image}")
  134. photo = ImageTk.PhotoImage(image)
  135. image_label.config(image=photo)
  136. image_label.image = photo # 保持对图片的引用
  137. except FileNotFoundError:
  138. logging.error(f"图片不存在")
  139. pass
  140. def create_content_area(self):
  141. self.content_frame = tk.Frame(self)
  142. self.content_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True)
  143. def show_content(self, item: AbsControl):
  144. print(f"---> {item.name},{self._content_cache}")
  145. for key, value in self._content_cache.items():
  146. if key != item.name:
  147. value.pack_forget()
  148. if item.name in self._content_cache:
  149. content = self._content_cache[item.name]
  150. content.pack(fill=tk.BOTH, expand=True)
  151. else:
  152. content = tk.Frame(self.content_frame)
  153. content.pack(fill=tk.BOTH, expand=True)
  154. # 表单区域
  155. form_frame = tk.Frame(content)
  156. form_frame.pack(side=tk.TOP, fill=tk.X)
  157. # 设置第二列的权重
  158. # form_frame.columnconfigure(1, weight=1)
  159. tk.Label(form_frame, text="连接:").grid(row=0, column=0, sticky="w")
  160. name_entry = Entry(form_frame, width=100)
  161. name_entry.grid(row=0, column=1)
  162. name_entry.insert(0, '127.0.0.1:6555')
  163. # 图片预览区域
  164. image_label = Label(content, width=200, height=380)
  165. 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")
  166. Button(form_frame, text="查看手机", command=lambda n=name_entry: self.flush_screenshot(item, image_label)).grid(row=0, column=2, sticky="e")
  167. # tk.Label(form_frame, text="年龄:").grid(row=1, column=0, sticky="w")
  168. # age_entry = Entry(form_frame)
  169. # age_entry.grid(row=1, column=1)
  170. #
  171. # Button(form_frame, text="保存").grid(row=2, column=1, sticky="e")
  172. # 日志区域
  173. log_text = Text(content, height=10)
  174. log_text.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
  175. log_text.insert(tk.END, f"导航 {item} 被点击\n")
  176. item.set_log_func(lambda msg: log_text.insert(tk.END, f"{msg}\n"))
  177. image_label.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True)
  178. # self.flush_screenshot(image_label)
  179. self._content_cache[item.name] = content # 缓存内容