main_ui.py 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. import logging
  2. import tempfile
  3. import tkinter as tk
  4. from tkinter import Menu, Text, Label, Entry, Button, ttk
  5. from typing import Dict
  6. from PIL import Image, ImageTk # 需要安装 Pillow 库
  7. from control.base.base_control import AbsControl, BaseControl
  8. from control.ui.settings_control import SettingsControl
  9. from gui.phone_list import PhoneListUI
  10. from gui.settings import SettingUI
  11. from utils.config import version
  12. from utils.control_util import ControlUtils
  13. CACHE_KEY_SETTING = 'settings'
  14. CACHE_KEY_PHONE_LIST = 'phone_list'
  15. keys_mapping = {
  16. "F1": "开仓滑竿",
  17. "F2": "买入/开多",
  18. "F3": "平仓滑竿",
  19. "F4": "卖出/平多",
  20. "F5": "开仓滑竿",
  21. "F6": "开仓/开空",
  22. "F7": "平仓滑竿",
  23. "F8": "卖出/平空"
  24. }
  25. class Application(tk.Tk):
  26. """
  27. 页面布局
  28. """
  29. def __init__(self, controls=None):
  30. super().__init__()
  31. self.notebook = None
  32. if controls is None:
  33. controls = {}
  34. self._controls: Dict[str, AbsControl] = controls # 控件
  35. # self.content_frame = None
  36. self.navigation_buttons = None
  37. self.navigation_frame = None
  38. self.title(f"群控小助手[{version}]")
  39. self.geometry("1366x768")
  40. self.create_menu()
  41. # self.create_navigation()
  42. self.create_content_area()
  43. # self._event_build()
  44. self._content_cache = {} # 缓存内容
  45. def create_menu(self):
  46. menubar = Menu(self)
  47. self.config(menu=menubar)
  48. menu1 = Menu(menubar, tearoff=0)
  49. menu1.add_command(label="设置(S)", command=lambda: self.click_settings())
  50. menu1.add_command(label="手机(T)", command=lambda: self.click_phone_list())
  51. menu1.add_command(label="退出(Q)", command=self.quit)
  52. menubar.add_cascade(label="视图", menu=menu1)
  53. menu1 = Menu(menubar, tearoff=0)
  54. menu1.add_command(label="关于", command=lambda: self.more_click('', "关于"))
  55. menubar.add_cascade(label="帮助", menu=menu1)
  56. def create_content_area(self):
  57. # """创建主内容区域"""
  58. # self.content_frame = tk.Frame(self)
  59. # self.content_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
  60. # 创建一个 Style 实例
  61. style = ttk.Style()
  62. notebook_style_name = "main_ui.TNotebook"
  63. style.configure(notebook_style_name) # 可以进行其他配置,如果需要
  64. style.layout(notebook_style_name + ".Tab", [])
  65. self.notebook = ttk.Notebook(self, style=notebook_style_name) # 将自定义样式应用到这个 Notebook
  66. self.notebook.pack(fill="both", expand=True)
  67. def _toggle_content(self, name: str):
  68. """根据标签文本选择 Notebook 中的选项卡。"""
  69. logging.info(f"打开页面 '{name}' 。")
  70. for index in range(self.notebook.index("end")):
  71. if self.notebook.tab(index, "text") == name:
  72. self.notebook.select(index)
  73. return True
  74. return False
  75. def click_settings(self):
  76. """显示设置界面"""
  77. # has = CACHE_KEY_SETTING in self._content_cache
  78. logging.info(f"点击了设置:{SettingUI.__name__}")
  79. #
  80. # # 创建或获取UI
  81. if not self._toggle_content(SettingUI.__name__):
  82. ui = SettingUI(control=self._controls[SettingsControl.__name__])
  83. self.notebook.add(ui, text=SettingUI.__name__)
  84. self._toggle_content(SettingUI.__name__)
  85. def click_phone_list(self):
  86. """
  87. 显示手机列表
  88. """
  89. logging.info(f"点击了设置,缓存命中:{PhoneListUI.__name__}")
  90. # 清空其他所有内容
  91. if not self._toggle_content(PhoneListUI.__name__):
  92. ui = PhoneListUI(control=ControlUtils())
  93. self.notebook.add(ui, text=PhoneListUI.__name__)
  94. self._toggle_content(PhoneListUI.__name__)
  95. # 多点击事件,循环调用
  96. def more_click(self, key, msg):
  97. print(msg)
  98. #
  99. # for item in self._controls:
  100. # item.print_log(msg)
  101. # met_name = f'event_{key.lower()}'
  102. # if hasattr(item, met_name):
  103. # evt = getattr(item, met_name)
  104. # evt()
  105. # else:
  106. # print(f"实例 {item.name}没有名为 '{key}' 的方法")
  107. #
  108. # def add_control(self, control: AbsControl):
  109. # self._controls.append(control)
  110. #
  111. # def _event_build(self):
  112. # def _bind_command(key, label):
  113. # self.bind_all(f"<{key}>", lambda event: self.more_click(key, label))
  114. #
  115. # for key, value in keys_mapping.items():
  116. # label = f"{value}({key})"
  117. # logging.info(f'绑定事件:{label}')
  118. # _bind_command(key, label)
  119. # def create_navigation(self):
  120. # self.navigation_frame = tk.Frame(self, width=150, bg="#f0f0f0")
  121. # self.navigation_frame.pack(side=tk.LEFT, fill=tk.Y)
  122. #
  123. # for item in self._controls:
  124. # # image = Image.open(item['logo'])
  125. # # photo = ImageTk.PhotoImage(image)
  126. # logging.info(f"导航按钮:{item.name}->{item.ctx}")
  127. # button = tk.Button(self.navigation_frame, text=item.name, command=lambda i=item:
  128. # self.init_connect_content(i) if i.ctx == 1 else \
  129. # self.plat_content(i)
  130. # # if item.ctx == 1 else self.plat_content(i),
  131. # , compound=tk.LEFT)
  132. # button.pack(fill=tk.X, pady=5)
  133. # # self.navigation_buttons.append(button)
  134. # def test_connect(self, control: AbsControl, serial: str, img: Label = None):
  135. # logging.info(f"测试连接:{serial}")
  136. #
  137. # if serial.startswith("adb connect"):
  138. # serial = serial.split('connect')[1].strip()
  139. #
  140. # control.connect_adb(serial)
  141. #
  142. # self.flush_screenshot(control, img)
  143. def flush_screenshot(self, control: AbsControl, image_label: Label):
  144. """
  145. 刷新截图
  146. """
  147. control.screenshot()
  148. try:
  149. tmp = tempfile.gettempdir()
  150. image = Image.open(f"{tmp}/{control.name}.png")
  151. logging.info(f"图片存放路径:{tmp}/{control.name}.png")
  152. w = 380
  153. image = image.resize((w, w * 16 // 9))
  154. logging.info(f"刷新截图:{image}")
  155. photo = ImageTk.PhotoImage(image)
  156. image_label.config(image=photo)
  157. image_label.image = photo # 保持对图片的引用
  158. except FileNotFoundError:
  159. logging.error(f"图片不存在")
  160. pass
  161. # def plat_content(self, item: AbsControl):
  162. # print(f"plat_content---> {item.name},{self._content_cache}")
  163. # for key, value in self._content_cache.items():
  164. # if key != item.name:
  165. # value.pack_forget()
  166. #
  167. # content: tk.Frame
  168. #
  169. # if item.name in self._content_cache:
  170. # content = self._content_cache[item.name]
  171. # else:
  172. # content = tk.Frame(self.content_frame)
  173. # # 表单区域
  174. # form_frame = tk.Frame(content)
  175. # form_frame.pack(side=tk.TOP, fill=tk.X)
  176. # # 设置第二列的权重
  177. # # form_frame.columnconfigure(1, weight=1)
  178. # tk.Label(form_frame, text="连接:").grid(row=0, column=0, sticky="w")
  179. # name_entry = Entry(form_frame, width=100)
  180. # name_entry.grid(row=0, column=1)
  181. # info = BaseControl.connect_dict[item.get_app_package_name()]
  182. # name_entry.insert(0, info['device'])
  183. # # 图片预览区域
  184. # image_label = Label(content, width=200, height=380)
  185. # Button(form_frame, text="测试连接",
  186. # command=lambda n=name_entry: self.test_connect(item, name_entry.get(), image_label)).grid(row=0,
  187. # column=1,
  188. # sticky="e")
  189. # Button(form_frame, text="查看手机",
  190. # command=lambda n=name_entry: self.flush_screenshot(item, image_label)).grid(row=0, column=2,
  191. # sticky="e")
  192. #
  193. # # 日志区域
  194. # log_text = Text(content, height=10)
  195. # log_text.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
  196. # log_text.insert(tk.END, f"导航 {item.name} 被点击\n")
  197. #
  198. # item.set_log_func(lambda msg: log_text.insert(tk.END, f"{msg}\n"))
  199. #
  200. # image_label.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True)
  201. # # self.flush_screenshot(image_label)
  202. # self._content_cache[item.name] = content # 缓存内容
  203. #
  204. # content.pack(fill=tk.BOTH, expand=True)