settings.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. import logging
  2. import tkinter as tk
  3. from tkinter import ttk
  4. from typing import List
  5. from control.base.base_control import BaseControl, AbsControl
  6. from utils.config import version
  7. class _SettingsConnect(tk.Frame):
  8. """
  9. 连接云手机
  10. """
  11. def __init__(self, master=None, control: BaseControl = None, cnf=None, **kw):
  12. super().__init__(master, cnf if cnf is not None else {}, **kw)
  13. self.control = control
  14. self.init_ui()
  15. self.pack(padx=10, pady=10)
  16. def init_ui(self):
  17. """
  18. 初始化连接
  19. 云手机开启 ABD后无法自动识别,需要通过shell 连接一下。
  20. :return:
  21. """
  22. logging.info(f"连接云手机--->")
  23. content = ttk.Frame(self)
  24. content.pack(fill=tk.BOTH, expand=True)
  25. fieldset = ttk.LabelFrame(content, text="连接信息")
  26. fieldset.grid(row=0, column=0, padx=10, pady=10, sticky="nsew")
  27. content.grid_columnconfigure(0, weight=1)
  28. content.grid_rowconfigure(0, weight=1)
  29. fieldset.grid_columnconfigure(0, weight=1)
  30. fieldset.grid_rowconfigure(1, weight=1)
  31. cmd_label = ttk.Label(fieldset, text="ADB连接(一行一个):")
  32. cmd_label.grid(row=0, column=0, padx=5, pady=5, sticky="nw")
  33. cmd_text = tk.Text(fieldset, height=10)
  34. cmd_text.grid(row=1, column=0, columnspan=2, padx=5, pady=5, sticky="nsew")
  35. def insert_advice_list() -> None:
  36. devices = self.control.devices_list(**{'top': self, 'log': log_text})
  37. logging.info(f"设备连接信息:{devices}")
  38. if devices:
  39. for device in devices:
  40. cmd_text.insert(tk.END, f"\nadb connect {device}\n")
  41. auto_btn = ttk.Button(fieldset, text="检查连接", command=lambda: insert_advice_list())
  42. auto_btn.grid(row=2, column=1, padx=(5, 2), pady=5, sticky="nw")
  43. test_btn = ttk.Button(fieldset, text="连接云手机",
  44. command=lambda: self.control.init_adb(cmd_text.get('1.0', tk.END).split('\n'),
  45. **{'top': self, 'log': log_text}))
  46. test_btn.grid(row=2, column=0, padx=(2, 5), pady=5, sticky="nw")
  47. # 日志区域
  48. log_label = ttk.Label(content, text="连接信息:")
  49. log_label.grid(row=1, column=0, padx=5, pady=5, sticky="nw")
  50. log_text = tk.Text(content, height=10)
  51. log_text.grid(row=2, column=0, padx=10, pady=(0, 10), sticky="nsew")
  52. content.grid_rowconfigure(2, weight=1)
  53. class _SettingsKey(tk.Frame):
  54. """
  55. 设置快捷键
  56. """
  57. keys_mappings = {
  58. '买入/开多': {'ctrl': False, 'shift': False, 'alt': False, 'key': ''},
  59. '买入/平多': {'ctrl': False, 'shift': False, 'alt': False, 'key': ''},
  60. '卖出/开空': {'ctrl': False, 'shift': False, 'alt': False, 'key': ''},
  61. '卖出/平空': {'ctrl': False, 'shift': False, 'alt': False, 'key': ''},
  62. "一键撤单": {'ctrl': False, 'shift': False, 'alt': False, 'key': ''},
  63. '撤销委托': {'ctrl': False, 'shift': False, 'alt': False, 'key': ''},
  64. }
  65. def __init__(self, master=None, cnf=None, **kw):
  66. super().__init__(master, cnf if cnf is not None else {}, **kw)
  67. self.control = None
  68. self.init_ui()
  69. self.pack(padx=10, pady=10)
  70. def init_ui(self):
  71. # 快捷键设置
  72. fieldset = ttk.LabelFrame(self, text="快捷键设置")
  73. fieldset.grid(row=0, column=0, padx=10, pady=10, sticky="nsew")
  74. fieldset.grid_columnconfigure(0, weight=1)
  75. fieldset.grid_rowconfigure(1, weight=1)
  76. # 配置Checkbutton样式
  77. style = ttk.Style()
  78. style.configure("TCheckbutton", )
  79. # 循环 keys_mappings
  80. for i, (key, value) in enumerate(self.keys_mappings.items()):
  81. # 创建一个 frame 来保存当前行的所有控件
  82. row_frame = ttk.Frame(fieldset)
  83. row_frame.grid(row=i, column=0, sticky="ew", padx=5, pady=5)
  84. # 创建说明标签
  85. label = ttk.Label(row_frame, text=f"{key:<7}:")
  86. label.pack(side=tk.LEFT, padx=(0, 10))
  87. # 为每个按键组合创建变量并保存在字典中
  88. key_state = {
  89. 'name': key,
  90. 'ctrl_var': tk.BooleanVar(value=value['ctrl']),
  91. 'alt_var': tk.BooleanVar(value=value['alt']),
  92. 'shift_var': tk.BooleanVar(value=value['shift']),
  93. 'key_var': tk.StringVar(value=value['key'])
  94. }
  95. # 创建复选框
  96. ttk.Checkbutton(row_frame, text="Ctrl", variable=key_state['ctrl_var'],
  97. command=lambda state=key_state: self._on_checkbox_click(state)).pack(side=tk.LEFT, padx=5)
  98. ttk.Checkbutton(row_frame, text="Alt", variable=key_state['alt_var'],
  99. command=lambda state=key_state: self._on_checkbox_click(state)).pack(side=tk.LEFT, padx=5)
  100. ttk.Checkbutton(row_frame, text="Shift", variable=key_state['shift_var'],
  101. command=lambda state=key_state: self._on_checkbox_click(state)).pack(side=tk.LEFT, padx=5)
  102. # 创建下拉框
  103. options = [chr(i) for i in range(65, 91)] + [f"F{i}" for i in range(1, 13)]
  104. combo = ttk.Combobox(row_frame, textvariable=key_state['key_var'], values=options,
  105. width=8, state='readonly', )
  106. combo.bind('<<ComboboxSelected>>', lambda event, state=key_state: self._on_checkbox_click(state))
  107. # 如果key_state中已有值就使用已有值,否则设置为第一个选项
  108. if key_state['key_var'].get():
  109. combo.set(key_state['key_var'].get())
  110. else:
  111. combo.current(i) # 设置第一个选项为默认值
  112. combo.pack(side=tk.LEFT, padx=5)
  113. # idx = len(self.keys_mappings)
  114. # save_btn = ttk.Button(self, text="保存",
  115. # command=lambda: print('保存快捷键设置'))
  116. # save_btn.grid(row=idx + 1, column=0, padx=5, pady=5, sticky="nwe")
  117. # test_btn = ttk.Button(self, text="恢复默认",
  118. # command=lambda: print('恢复默认'))
  119. # test_btn.grid(row=idx + 2, column=0, padx=5, pady=5, sticky="nwe")
  120. def _on_checkbox_click(self, key_state: dict):
  121. """
  122. 复选框点击事件处理
  123. """
  124. # 获取当前状态
  125. name = key_state['name']
  126. ctrl_state = key_state['ctrl_var'].get()
  127. alt_state = key_state['alt_var'].get()
  128. shift_state = key_state['shift_var'].get()
  129. key = key_state['key_var'].get()
  130. # 更新映射
  131. self.keys_mappings[name].update({
  132. 'ctrl': ctrl_state,
  133. 'alt': alt_state,
  134. 'shift': shift_state,
  135. 'key': key
  136. })
  137. logging.info(f"快捷键 '{name}' 更新: Ctrl={ctrl_state}, Alt={alt_state}, Shift={shift_state}, Key={key}")
  138. self._key_binds(name)
  139. def _key_binds(self, name: str):
  140. """
  141. 绑定快捷键
  142. :param name:
  143. :return:
  144. """
  145. key = self.keys_mappings[name]
  146. logging.info(f"<UNK> '{key}' <UNK>")
  147. key_combo = []
  148. if key['ctrl']:
  149. key_combo.append('Control')
  150. if key['shift']:
  151. key_combo.append('Shift')
  152. if key['alt']:
  153. key_combo.append('Alt')
  154. # 组合所有激活的修饰键
  155. if key_combo:
  156. key_bind = f"<{'-'.join(key_combo)}-{key['key'].lower()}>"
  157. self.winfo_toplevel().unbind_all(key_bind)
  158. self.winfo_toplevel().bind_all(key_bind, lambda event: self._demo_click(f'-->{name}'))
  159. logging.info(f'绑定快捷键: {key_bind} --> {name}')
  160. else:
  161. # 如果没有修饰键,直接绑定键值
  162. self.winfo_toplevel().unbind_all(f"<{key['key'].lower()}>")
  163. self.winfo_toplevel().bind_all(f"<{key['key'].lower()}>", lambda event: self._demo_click(f'-->{name}'))
  164. logging.info(f"<{key['key']}=> {name} ")
  165. pass
  166. def _demo_click(self, event):
  167. logging.info(f"<DEMO> {event} <DEMO>")
  168. def _keys_binds(self, keys: List[dict]):
  169. """
  170. 返回快捷键映射
  171. :param keys: [{'ctrl':True,'shift':True,'alt':True,'key':'a'},...]
  172. :return:
  173. """
  174. # 循环 keys 绑定快捷键, self.control
  175. for i, key in enumerate(keys):
  176. # 绑定快捷键
  177. self.init_ui(keys)
  178. class _SettingsOther(tk.Frame):
  179. """
  180. 其他设置
  181. """
  182. def __init__(self, master=None, cnf=None, **kw):
  183. super().__init__(master, cnf if cnf is not None else {}, **kw)
  184. self.tel_connect = None
  185. self.control = None
  186. self.init_ui()
  187. def init_ui(self):
  188. # 创建并配置notebook
  189. notebook = ttk.Notebook(self)
  190. # 设置notebook的填充
  191. notebook.pack(anchor="w", fill=tk.BOTH, expand=True)
  192. class _SettingsAbout(tk.Frame):
  193. """
  194. 关于
  195. """
  196. def __init__(self, master=None, cnf=None, **kw):
  197. super().__init__(master, cnf if cnf is not None else {}, **kw)
  198. self.init_ui()
  199. self.pack(padx=10, pady=10)
  200. def init_ui(self):
  201. # 创建一个 Frame 来模拟 <fieldset>
  202. fieldset = ttk.LabelFrame(self, text="群控助手")
  203. fieldset.grid(row=0, column=0, padx=10, pady=10, sticky="nw")
  204. self.grid_columnconfigure(0, weight=1)
  205. self.grid_rowconfigure(0, weight=0)
  206. fieldset.grid_columnconfigure(0, weight=1)
  207. fieldset.grid_rowconfigure(1, weight=1)
  208. cmd_label = ttk.Label(fieldset, text=f"版本:{version}")
  209. cmd_label.grid(row=0, column=0, padx=5, pady=5, sticky="nw")
  210. cmd_label = ttk.Label(fieldset, text=f"作者:强哥")
  211. cmd_label.grid(row=2, column=0, padx=5, pady=5, sticky="nw")
  212. cmd_label = ttk.Label(fieldset, text=f"邮箱:fzxs88@yeah.net")
  213. cmd_label.grid(row=3, column=0, padx=5, pady=5, sticky="nw")
  214. class SettingUI(tk.Frame):
  215. """
  216. 设置页面
  217. """
  218. def __init__(self, master=None, control: BaseControl = None, cnf=None, **kw):
  219. super().__init__(master, cnf if cnf is not None else {}, **kw)
  220. self.about = None
  221. self.options = None
  222. self.key_mapping = None
  223. self.tel_connect = None
  224. self.control = control
  225. self.init_ui()
  226. def init_ui(self):
  227. # 创建并配置notebook
  228. notebook = ttk.Notebook(self)
  229. #
  230. # 设置notebook的填充
  231. notebook.pack(anchor="w", fill=tk.BOTH, expand=True)
  232. #
  233. # 第一个选项卡的内容
  234. self.tel_connect = ttk.Frame(notebook)
  235. notebook.add(self.tel_connect, text="连接云手机")
  236. _SettingsConnect(master=self.tel_connect, control=self.control)
  237. # 第二个选项卡的内容
  238. self.key_mapping = ttk.Frame(notebook)
  239. notebook.add(self.key_mapping, text="设置快捷键")
  240. _SettingsKey(self.key_mapping)
  241. # 第三个选项卡的内容
  242. self.options = ttk.Frame(notebook)
  243. notebook.add(self.options, text="其他设置")
  244. label3 = ttk.Label(self.options, text="其他设置")
  245. label3.pack(padx=10, pady=10)
  246. # 第四个选项卡的内容
  247. self.about = ttk.Frame(notebook)
  248. notebook.add(self.about, text="关于")
  249. _SettingsAbout(self.about)