import logging import tkinter as tk from tkinter import ttk from typing import List from control.base.base_control import BaseControl, AbsControl from utils.config import version class _SettingsConnect(tk.Frame): """ 连接云手机 """ def __init__(self, master=None, control: BaseControl = None, cnf=None, **kw): super().__init__(master, cnf if cnf is not None else {}, **kw) self.control = control self.init_ui() self.pack(padx=10, pady=10) def init_ui(self): """ 初始化连接 云手机开启 ABD后无法自动识别,需要通过shell 连接一下。 :return: """ logging.info(f"连接云手机--->") content = ttk.Frame(self) content.pack(fill=tk.BOTH, expand=True) fieldset = ttk.LabelFrame(content, text="连接信息") fieldset.grid(row=0, column=0, padx=10, pady=10, sticky="nsew") content.grid_columnconfigure(0, weight=1) content.grid_rowconfigure(0, weight=1) fieldset.grid_columnconfigure(0, weight=1) fieldset.grid_rowconfigure(1, weight=1) cmd_label = ttk.Label(fieldset, text="ADB连接(一行一个):") cmd_label.grid(row=0, column=0, padx=5, pady=5, sticky="nw") cmd_text = tk.Text(fieldset, height=10) cmd_text.grid(row=1, column=0, columnspan=2, padx=5, pady=5, sticky="nsew") def insert_advice_list() -> None: devices = self.control.devices_list() if devices: for device in devices: cmd_text.insert(tk.END, f"adb connect {device}\n") auto_btn = ttk.Button(fieldset, text="检查连接", command=lambda: insert_advice_list()) auto_btn.grid(row=2, column=1, padx=(5, 2), pady=5, sticky="nw") test_btn = ttk.Button(fieldset, text="连接云手机", command=lambda: self.control.init_adb(cmd_text.get('1.0', tk.END).split('\n'), log_text, **{'ui': self})) test_btn.grid(row=2, column=0, padx=(2, 5), pady=5, sticky="nw") # 日志区域 log_label = ttk.Label(content, text="连接信息:") log_label.grid(row=1, column=0, padx=5, pady=5, sticky="nw") log_text = tk.Text(content, height=10) log_text.grid(row=2, column=0, padx=10, pady=(0, 10), sticky="nsew") content.grid_rowconfigure(2, weight=1) # def _connect_adb(self, cmd_text, log_text): # # 创建加载指示器 # # def func(): # self.control.init_adb(cmd_text.get('1.0', tk.END).split('\n'), log_text) # # self.control.loadding(self, func) # loading_window = tk.Toplevel(self) # loading_window.title("连接中") # loading_window.geometry("200x100") # loading_window.transient(self) # 设置为模态 # loading_window.grab_set() # 设置为模态 # loading_window.overrideredirect(True) # 移除窗口边框和按钮 # # 相对于父窗口居中显示 # window_width = loading_window.winfo_reqwidth() # window_height = loading_window.winfo_reqheight() # parent_x = self.winfo_rootx() # parent_y = self.winfo_rooty() # parent_width = self.winfo_width() # parent_height = self.winfo_height() # position_right = parent_x + (parent_width - window_width) // 2 # position_down = parent_y + (parent_height - window_height) // 2 # loading_window.geometry(f"+{position_right}+{position_down}") # loading_label = ttk.Label(loading_window, text="连接中...", padding=20) # loading_label.pack(expand=True) # # def thread_task(): # try: # self.control.init_adb(cmd_text.get('1.0', tk.END).split('\n'), log_text) # finally: # # 在主线程中销毁加载指示器 # self.after(0, lambda: [loading_window.grab_release(), loading_window.destroy()]) # # import threading # thread = threading.Thread(target=thread_task) # # thread.daemon = True # 设置为守护线程,这样主程序退出时线程会自动结束 # thread.start() class _SettingsKey(tk.Frame): """ 设置快捷键 """ keys_mappings = { '买入/开多': {'ctrl': False, 'shift': False, 'alt': False, 'key': ''}, '买入/平多': {'ctrl': False, 'shift': False, 'alt': False, 'key': ''}, '卖出/开空': {'ctrl': False, 'shift': False, 'alt': False, 'key': ''}, '卖出/平空': {'ctrl': False, 'shift': False, 'alt': False, 'key': ''}, "一键撤单": {'ctrl': False, 'shift': False, 'alt': False, 'key': ''}, '撤销委托': {'ctrl': False, 'shift': False, 'alt': False, 'key': ''}, } def __init__(self, master=None, cnf=None, **kw): super().__init__(master, cnf if cnf is not None else {}, **kw) self.control = None self.init_ui() self.pack(padx=10, pady=10) def init_ui(self): # 快捷键设置 fieldset = ttk.LabelFrame(self, text="快捷键设置") fieldset.grid(row=0, column=0, padx=10, pady=10, sticky="nsew") fieldset.grid_columnconfigure(0, weight=1) fieldset.grid_rowconfigure(1, weight=1) # 配置Checkbutton样式 style = ttk.Style() style.configure("TCheckbutton", ) # 循环 keys_mappings for i, (key, value) in enumerate(self.keys_mappings.items()): # 创建一个 frame 来保存当前行的所有控件 row_frame = ttk.Frame(fieldset) row_frame.grid(row=i, column=0, sticky="ew", padx=5, pady=5) # 创建说明标签 label = ttk.Label(row_frame, text=f"{key:<7}:") label.pack(side=tk.LEFT, padx=(0, 10)) # 为每个按键组合创建变量并保存在字典中 key_state = { 'name': key, 'ctrl_var': tk.BooleanVar(value=value['ctrl']), 'alt_var': tk.BooleanVar(value=value['alt']), 'shift_var': tk.BooleanVar(value=value['shift']), 'key_var': tk.StringVar(value=value['key']) } # 创建复选框 ttk.Checkbutton(row_frame, text="Ctrl", variable=key_state['ctrl_var'], command=lambda state=key_state: self._on_checkbox_click(state)).pack(side=tk.LEFT, padx=5) ttk.Checkbutton(row_frame, text="Alt", variable=key_state['alt_var'], command=lambda state=key_state: self._on_checkbox_click(state)).pack(side=tk.LEFT, padx=5) ttk.Checkbutton(row_frame, text="Shift", variable=key_state['shift_var'], command=lambda state=key_state: self._on_checkbox_click(state)).pack(side=tk.LEFT, padx=5) # 创建下拉框 options = [chr(i) for i in range(65, 91)] + [f"F{i}" for i in range(1, 13)] combo = ttk.Combobox(row_frame, textvariable=key_state['key_var'], values=options, width=8, state='readonly', ) combo.bind('<>', lambda event, state=key_state: self._on_checkbox_click(state)) # 如果key_state中已有值就使用已有值,否则设置为第一个选项 if key_state['key_var'].get(): combo.set(key_state['key_var'].get()) else: combo.current(i) # 设置第一个选项为默认值 combo.pack(side=tk.LEFT, padx=5) # idx = len(self.keys_mappings) # save_btn = ttk.Button(self, text="保存", # command=lambda: print('保存快捷键设置')) # save_btn.grid(row=idx + 1, column=0, padx=5, pady=5, sticky="nwe") # test_btn = ttk.Button(self, text="恢复默认", # command=lambda: print('恢复默认')) # test_btn.grid(row=idx + 2, column=0, padx=5, pady=5, sticky="nwe") def _on_checkbox_click(self, key_state: dict): """ 复选框点击事件处理 """ # 获取当前状态 name = key_state['name'] ctrl_state = key_state['ctrl_var'].get() alt_state = key_state['alt_var'].get() shift_state = key_state['shift_var'].get() key = key_state['key_var'].get() # 更新映射 self.keys_mappings[name].update({ 'ctrl': ctrl_state, 'alt': alt_state, 'shift': shift_state, 'key': key }) logging.info(f"快捷键 '{name}' 更新: Ctrl={ctrl_state}, Alt={alt_state}, Shift={shift_state}, Key={key}") self._key_binds(name) def _key_binds(self, name: str): """ 绑定快捷键 :param name: :return: """ key = self.keys_mappings[name] logging.info(f" '{key}' ") key_combo = [] if key['ctrl']: key_combo.append('Control') if key['shift']: key_combo.append('Shift') if key['alt']: key_combo.append('Alt') # 组合所有激活的修饰键 if key_combo: key_bind = f"<{'-'.join(key_combo)}-{key['key'].lower()}>" self.winfo_toplevel().unbind_all(key_bind) self.winfo_toplevel().bind_all(key_bind, lambda event: self._demo_click(f'-->{name}')) logging.info(f'绑定快捷键: {key_bind} --> {name}') else: # 如果没有修饰键,直接绑定键值 self.winfo_toplevel().unbind_all(f"<{key['key'].lower()}>") self.winfo_toplevel().bind_all(f"<{key['key'].lower()}>", lambda event: self._demo_click(f'-->{name}')) logging.info(f"<{key['key']}=> {name} ") pass def _demo_click(self, event): logging.info(f" {event} ") def _keys_binds(self, keys: List[dict]): """ 返回快捷键映射 :param keys: [{'ctrl':True,'shift':True,'alt':True,'key':'a'},...] :return: """ # 循环 keys 绑定快捷键, self.control for i, key in enumerate(keys): # 绑定快捷键 self.init_ui(keys) class _SettingsOther(tk.Frame): """ 其他设置 """ def __init__(self, master=None, cnf=None, **kw): super().__init__(master, cnf if cnf is not None else {}, **kw) self.tel_connect = None self.control = None self.init_ui() def init_ui(self): # 创建并配置notebook notebook = ttk.Notebook(self) # 设置notebook的填充 notebook.pack(anchor="w", fill=tk.BOTH, expand=True) class _SettingsAbout(tk.Frame): """ 关于 """ def __init__(self, master=None, cnf=None, **kw): super().__init__(master, cnf if cnf is not None else {}, **kw) self.init_ui() self.pack(padx=10, pady=10) def init_ui(self): # 创建一个 Frame 来模拟
fieldset = ttk.LabelFrame(self, text="群控助手") fieldset.grid(row=0, column=0, padx=10, pady=10, sticky="nw") self.grid_columnconfigure(0, weight=1) self.grid_rowconfigure(0, weight=0) fieldset.grid_columnconfigure(0, weight=1) fieldset.grid_rowconfigure(1, weight=1) cmd_label = ttk.Label(fieldset, text=f"版本:{version}") cmd_label.grid(row=0, column=0, padx=5, pady=5, sticky="nw") cmd_label = ttk.Label(fieldset, text=f"作者:强哥") cmd_label.grid(row=2, column=0, padx=5, pady=5, sticky="nw") cmd_label = ttk.Label(fieldset, text=f"邮箱:fzxs88@yeah.net") cmd_label.grid(row=3, column=0, padx=5, pady=5, sticky="nw") class SettingUI(tk.Frame): """ 设置页面 """ def __init__(self, master=None, control: BaseControl = None, cnf=None, **kw): super().__init__(master, cnf if cnf is not None else {}, **kw) self.about = None self.options = None self.key_mapping = None self.tel_connect = None self.control = control self.init_ui() def init_ui(self): # 创建并配置notebook notebook = ttk.Notebook(self) # # 设置notebook的填充 notebook.pack(anchor="w", fill=tk.BOTH, expand=True) # # 第一个选项卡的内容 self.tel_connect = ttk.Frame(notebook) notebook.add(self.tel_connect, text="连接云手机") _SettingsConnect(master=self.tel_connect, control=self.control) # 第二个选项卡的内容 self.key_mapping = ttk.Frame(notebook) notebook.add(self.key_mapping, text="设置快捷键") _SettingsKey(self.key_mapping) # 第三个选项卡的内容 self.options = ttk.Frame(notebook) notebook.add(self.options, text="其他设置") label3 = ttk.Label(self.options, text="其他设置") label3.pack(padx=10, pady=10) # 第四个选项卡的内容 self.about = ttk.Frame(notebook) notebook.add(self.about, text="关于") _SettingsAbout(self.about)