先声明:代码由本人编写,但是由于本人代码编写不太规范,为了方便理解,所以让AI添加注释并且修改函数名

介绍
超级老板键:可以隐藏窗口,一键恢复多个窗口,可以隐藏自身。如图,可以点左下角添加配置,可以添加多个老板键隐藏多个窗口。点击右边“捕获”可以自定义老板键,配置会保存在当前目录下。隐藏有三个选项,可以自己选择:隐藏老板键自身,隐藏最表层窗口和隐藏指定窗口(要写窗口标题)。配置好后点击”启动老板键“即可开始使用,有一键恢复窗口。
下载链接https://yanhe520.lanzoub.com/b0uma9hkj
密码:huuv提供蓝奏云直接下载!
备注:因为我设置了无控制台(就是没有黑窗),所以360不知道为啥就报毒,各位不放心可以看看源码,或者自己反编译,spec也在附件中!,。以下内容便于检查人员反编译:python的打包版本:"""E:\练手项目\项目3老板键>python --version
Python 3.10.8
pyinstaller版本E:\练手项目\项目3老板键>pyinstaller -v
6.14.2"""
问题修复等内容
如果遇到问题或者bug可以打开老板键所在目录,底下会有log.txt文件,将文件和你的问题或bug发给我,我看到会处理。如果有其他想要的功能也可以私信我哦!
源代码:
- import os
- import sys
- # ---------- 隐藏控制台黑窗(仅 Windows)----------
- if sys.platform == "win32":
- import ctypes
- ctypes.windll.kernel32.FreeConsole()
- import tkinter as tk
- from tkinter import ttk, messagebox
- import threading
- import queue
- import json
- import logging
- # ---------- 依赖库 ----------
- import keyboard
- import pygetwindow as gw
- import win32gui
- import win32con
- import win32event
- import win32api
- import winerror
- # ---------- 日志配置(追加模式)----------
- LOG_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), "log.txt")
- logging.basicConfig(
- level=logging.INFO,
- format='%(asctime)s - %(levelname)s - %(message)s',
- handlers=[
- logging.FileHandler(LOG_FILE, mode='a', encoding='utf-8')
- ]
- )
- logger = logging.getLogger(__name__)
- CONFIG_FILE = "bosskey_config.json"
- # ---------- 进程互斥,防止多开 ----------
- MUTEX_NAME = "Global\\BossKeyAppMutex"
- mutex = win32event.CreateMutex(None, False, MUTEX_NAME)
- if win32api.GetLastError() == winerror.ERROR_ALREADY_EXISTS:
- logger.warning("检测到已有实例运行,退出")
- sys.exit(0)
- # ---------------------- 单个隐藏配置项的数据模型 ----------------------
- class HideConfigItem:
- """
- 一个隐藏规则:包含启用状态、类型、快捷键、目标标题,以及运行时隐藏的窗口句柄
- """
- # 内部英文标识
- HIDE_SELF = "self" # 隐藏自身窗口
- HIDE_TOPMOST = "topmost" # 隐藏最表层窗口
- HIDE_TARGET = "target" # 隐藏指定标题窗口
- # ★ 中文显示映射
- TYPE_MAP = {
- HIDE_SELF: "隐藏自身",
- HIDE_TOPMOST: "隐藏最表层窗口",
- HIDE_TARGET: "隐藏指定窗口"
- }
- REVERSE_MAP = {v: k for k, v in TYPE_MAP.items()}
- def __init__(self, enable=True, hide_type=HIDE_TOPMOST, hotkey="", target_title=""):
- self.enable = tk.BooleanVar(value=enable)
- self.hide_type = tk.StringVar(value=hide_type) # 内部英文
- self.hotkey = tk.StringVar(value=hotkey)
- self.target_title = tk.StringVar(value=target_title)
- # ★ 用于界面显示的中文变量,与 hide_type 自动同步
- self.type_display = tk.StringVar(value=self.TYPE_MAP.get(hide_type, "隐藏最表层窗口"))
- # 当 type_display 变化时,更新 hide_type
- self.type_display.trace("w", self._sync_hide_type)
- # 运行时状态
- self.hidden_hwnds = []
- self.hidden_self = False
- def _sync_hide_type(self, *args):
- """将中文显示值转换为英文内部值"""
- eng = self.REVERSE_MAP.get(self.type_display.get(), self.HIDE_TOPMOST)
- if self.hide_type.get() != eng:
- self.hide_type.set(eng)
- def get_hidden_any(self):
- if self.hide_type.get() == self.HIDE_SELF:
- return self.hidden_self
- elif self.hide_type.get() == self.HIDE_TOPMOST:
- return len(self.hidden_hwnds) > 0 and win32gui.IsWindow(self.hidden_hwnds[0])
- else:
- return any(win32gui.IsWindow(hwnd) for hwnd in self.hidden_hwnds)
- def to_dict(self):
- return {
- "enable": self.enable.get(),
- "type": self.hide_type.get(), # 保存英文标识
- "hotkey": self.hotkey.get(),
- "target_title": self.target_title.get()
- }
- @classmethod
- def from_dict(cls, data):
- item = cls(
- enable=data.get("enable", True),
- hide_type=data.get("type", cls.HIDE_TOPMOST),
- hotkey=data.get("hotkey", ""),
- target_title=data.get("target_title", "")
- )
- # 保证显示与内部值一致
- item.type_display.set(cls.TYPE_MAP.get(item.hide_type.get(), "隐藏最表层窗口"))
- return item
- class BossKeyApp:
- def __init__(self, root, auto_start=False):
- self.root = root
- self.root.title("老板键 v3.0 - 多配置版")
- self.root.geometry("620x550")
- self.root.resizable(True, True)
- self.root.protocol("WM_DELETE_WINDOW", self.on_closing)
- self.auto_start = auto_start
- # ---------- 动态配置列表 ----------
- self.config_items = []
- self.config_frames = []
- # ---------- 状态 ----------
- self.active = False
- self.action_queue = queue.Queue()
- self.registered_hotkeys = set()
- self.self_hidden = False
- self.load_config()
- self.build_ui()
- if self.auto_start:
- self.root.after(500, self.auto_elevated_start)
- self.process_queue()
- logger.info("程序启动")
- # ---------------------- 界面构建 ----------------------
- def build_ui(self):
- ttk.Label(self.root, text="老板键设置(可添加多条规则)", font=("微软雅黑", 12, "bold")).pack(pady=(10, 5))
- # ---------- 可滚动的配置列表区域 ----------
- container = ttk.Frame(self.root)
- container.pack(fill="both", expand=True, padx=20, pady=4)
- canvas = tk.Canvas(container, borderwidth=0, highlightthickness=0)
- scrollbar = ttk.Scrollbar(container, orient="vertical", command=canvas.yview)
- self.config_list_frame = ttk.Frame(canvas)
- self.config_list_frame.bind("<Configure>",
- lambda e: canvas.configure(scrollregion=canvas.bbox("all")))
- canvas.create_window((0, 0), window=self.config_list_frame, anchor="nw")
- canvas.configure(yscrollcommand=scrollbar.set)
- canvas.pack(side="left", fill="both", expand=True)
- scrollbar.pack(side="right", fill="y")
- def _on_mousewheel(event):
- canvas.yview_scroll(int(-1*(event.delta/120)), "units")
- canvas.bind_all("<MouseWheel>", _on_mousewheel)
- for item in self.config_items:
- self._add_config_row(item)
- if not self.config_items:
- default_item = HideConfigItem(hide_type=HideConfigItem.HIDE_TOPMOST, hotkey="ctrl+shift+f10")
- self.config_items.append(default_item)
- self._add_config_row(default_item)
- # ---------- 按钮区 ----------
- bottom_frame = ttk.Frame(self.root)
- bottom_frame.pack(pady=(8, 5), fill="x", padx=20)
- btn_add = ttk.Button(bottom_frame, text="添加配置项", command=self.add_config_item)
- btn_add.pack(side="left", padx=5)
- self.start_btn = ttk.Button(bottom_frame, text="启动老板键", command=self.start)
- self.start_btn.pack(side="left", padx=5)
- self.stop_btn = ttk.Button(bottom_frame, text="停止老板键", command=self.stop, state="disabled")
- self.stop_btn.pack(side="left", padx=5)
- self.recover_all_btn = ttk.Button(bottom_frame, text="一键恢复所有隐藏窗口", command=self.recover_all_windows)
- self.recover_all_btn.pack(side="left", padx=5)
- self.status_label = ttk.Label(self.root, text="状态:未启动", foreground="gray")
- self.status_label.pack(pady=(2, 10))
- def _add_config_row(self, item):
- frame = ttk.Frame(self.config_list_frame)
- frame.pack(fill="x", pady=3, padx=2)
- # 启用复选框
- cb = ttk.Checkbutton(frame, variable=item.enable)
- cb.pack(side="left", padx=(5, 2))
- # ★ 类型下拉(显示中文)
- type_combo = ttk.Combobox(frame, textvariable=item.type_display,
- values=["隐藏自身", "隐藏最表层窗口", "隐藏指定窗口"],
- state="readonly", width=14)
- type_combo.pack(side="left", padx=2)
- # 快捷键输入框
- hotkey_entry = ttk.Entry(frame, textvariable=item.hotkey, width=18, font=("Consolas", 10))
- hotkey_entry.pack(side="left", padx=2)
- # 捕获按钮
- btn_capture = ttk.Button(frame, text="捕获",
- command=lambda it=item: self.capture_hotkey(it.hotkey))
- btn_capture.pack(side="left", padx=2)
- # 目标标题输入(仅当类型为 target 时显示)
- title_entry = ttk.Entry(frame, textvariable=item.target_title, width=20)
- title_label = ttk.Label(frame, text="标题:")
- def update_title_visibility(*args):
- if item.hide_type.get() == HideConfigItem.HIDE_TARGET:
- title_label.pack(side="left", padx=(10, 2))
- title_entry.pack(side="left", padx=2)
- else:
- title_label.pack_forget()
- title_entry.pack_forget()
- item.hide_type.trace("w", update_title_visibility)
- update_title_visibility()
- # 删除按钮
- btn_del = ttk.Button(frame, text="删除",
- command=lambda f=frame, it=item: self.delete_config_item(f, it))
- btn_del.pack(side="right", padx=5)
- self.config_frames.append(frame)
- def add_config_item(self):
- new_item = HideConfigItem(hide_type=HideConfigItem.HIDE_TOPMOST, hotkey="")
- self.config_items.append(new_item)
- self._add_config_row(new_item)
- def delete_config_item(self, frame, item):
- if len(self.config_items) <= 1:
- messagebox.showinfo("提示", "至少保留一个配置项")
- return
- if self.active:
- messagebox.showwarning("提示", "请先停止老板键再删除配置")
- return
- self.config_items.remove(item)
- frame.destroy()
- self.config_frames.remove(frame)
- # ---------------------- 一键恢复所有隐藏窗口 ----------------------
- def recover_all_windows(self):
- recovered = 0
- if self.root.state() == "withdrawn":
- self.root.deiconify()
- self.root.lift()
- self.root.focus_force()
- recovered += 1
- logger.info("一键恢复:自身窗口已显示")
- for item in self.config_items:
- if item.hide_type.get() == HideConfigItem.HIDE_SELF:
- if self.root.state() == "withdrawn":
- pass
- else:
- for hwnd in item.hidden_hwnds:
- if win32gui.IsWindow(hwnd):
- win32gui.ShowWindow(hwnd, win32con.SW_SHOW)
- recovered += 1
- item.hidden_hwnds.clear()
- if item.hide_type.get() == HideConfigItem.HIDE_SELF:
- item.hidden_self = False
- self.action_queue.put(("status", f"一键恢复完成,共恢复 {recovered} 个窗口"))
- # ---------------------- 权限工具 ----------------------
- @staticmethod
- def is_admin():
- try:
- return ctypes.windll.shell32.IsUserAnAdmin()
- except:
- return False
- @staticmethod
- def run_as_admin():
- try:
- if getattr(sys, 'frozen', False):
- ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, '--elevated', None, 1)
- else:
- script = sys.argv[0]
- params = f'"{script}" --elevated'
- ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, params, None, 1)
- except Exception as e:
- logger.error(f"请求管理员权限失败: {e}")
- def auto_elevated_start(self):
- logger.info("以管理员权限静默启动老板键")
- self.start()
- if self.active:
- self.root.withdraw()
- logger.info("窗口已隐藏,后台监听热键")
- # ---------------------- 每个配置项的切换逻辑 ----------------------
- def toggle_by_item(self, item):
- t = item.hide_type.get()
- if t == HideConfigItem.HIDE_SELF:
- self._toggle_self(item)
- elif t == HideConfigItem.HIDE_TOPMOST:
- self._toggle_topmost(item)
- elif t == HideConfigItem.HIDE_TARGET:
- self._toggle_target(item)
- def _toggle_self(self, item):
- if self.root.state() == "withdrawn":
- self.root.deiconify()
- self.root.lift()
- self.root.focus_force()
- item.hidden_self = False
- self.action_queue.put(("status", "自身窗口已显示"))
- logger.info("自身窗口已显示")
- else:
- self.root.withdraw()
- item.hidden_self = True
- self.action_queue.put(("status", "自身窗口已隐藏"))
- logger.info("自身窗口已隐藏")
- def _toggle_topmost(self, item):
- if item.hidden_hwnds and win32gui.IsWindow(item.hidden_hwnds[0]):
- hwnd = item.hidden_hwnds[0]
- win32gui.ShowWindow(hwnd, win32con.SW_SHOW)
- title = win32gui.GetWindowText(hwnd)
- item.hidden_hwnds.clear()
- self.action_queue.put(("status", f"已恢复窗口:{title}"))
- logger.info(f"恢复最表层窗口:{title}")
- else:
- hwnd = win32gui.GetForegroundWindow()
- if hwnd:
- title = win32gui.GetWindowText(hwnd)
- if hwnd == self.root.winfo_id():
- self.action_queue.put(("status", "不能隐藏自身窗口,请使用自身隐藏规则"))
- return
- win32gui.ShowWindow(hwnd, win32con.SW_HIDE)
- item.hidden_hwnds = [hwnd]
- self.action_queue.put(("status", f"已隐藏窗口:{title}"))
- logger.info(f"隐藏最表层窗口:{title}")
- else:
- self.action_queue.put(("status", "未找到前台窗口"))
- def _toggle_target(self, item):
- if item.hidden_hwnds:
- restored = 0
- for hwnd in item.hidden_hwnds:
- if win32gui.IsWindow(hwnd):
- win32gui.ShowWindow(hwnd, win32con.SW_SHOW)
- restored += 1
- item.hidden_hwnds.clear()
- self.action_queue.put(("status", f"已显示 {restored} 个窗口"))
- logger.info(f"目标窗口已恢复,数量: {restored}")
- else:
- title = item.target_title.get().strip()
- if not title:
- self.action_queue.put(("status", "请填写目标窗口标题关键字!"))
- logger.warning("目标隐藏:标题为空")
- return
- matches = gw.getWindowsWithTitle(title)
- if not matches:
- self.action_queue.put(("status", f"未找到包含 '{title}' 的窗口"))
- logger.info(f"未找到匹配窗口: {title}")
- return
- hidden = 0
- for win in matches:
- if win.visible:
- win.hide()
- item.hidden_hwnds.append(win._hWnd)
- hidden += 1
- if hidden:
- self.action_queue.put(("status", f"已隐藏 {hidden} 个窗口"))
- logger.info(f"隐藏目标窗口: {title},数量: {hidden}")
- else:
- self.action_queue.put(("status", "没有可见的匹配窗口需要隐藏"))
- logger.info(f"没有可见的匹配窗口: {title}")
- # ---------------------- 热键注册(基于配置列表)---------------------
- def _start_hotkeys(self):
- try:
- registered = set()
- for item in self.config_items:
- if not item.enable.get():
- continue
- hk = item.hotkey.get().strip()
- if not hk:
- continue
- try:
- keyboard.remove_hotkey(hk)
- except:
- pass
- keyboard.add_hotkey(hk, lambda it=item: self.action_queue.put(("toggle_item", it)))
- registered.add(hk)
- logger.info(f"注册热键: {hk} (类型: {item.hide_type.get()})")
- self.registered_hotkeys = registered
- return True
- except Exception as e:
- logger.error(f"注册热键失败: {e}")
- return False
- def _stop_hotkeys(self):
- for hk in self.registered_hotkeys:
- try:
- keyboard.remove_hotkey(hk)
- except:
- pass
- self.registered_hotkeys.clear()
- for item in self.config_items:
- for hwnd in item.hidden_hwnds:
- if win32gui.IsWindow(hwnd):
- win32gui.ShowWindow(hwnd, win32con.SW_SHOW)
- item.hidden_hwnds.clear()
- if item.hide_type.get() == HideConfigItem.HIDE_SELF:
- item.hidden_self = False
- if self.root.state() == "withdrawn":
- self.root.deiconify()
- self.active = False
- self.start_btn.config(state="normal")
- self.stop_btn.config(state="disabled")
- self.status_label.config(text="状态:已停止")
- logger.info("老板键已停止")
- def start(self):
- if self.active:
- messagebox.showinfo("提示", "老板键已启动,无需重复操作")
- return
- valid = False
- for item in self.config_items:
- if item.enable.get() and item.hotkey.get().strip():
- valid = True
- break
- if not valid:
- messagebox.showwarning("提示", "请至少启用一个配置项并设置快捷键!")
- return
- if not self.is_admin():
- if not messagebox.askyesno("权限提示",
- "注册全局热键通常需要管理员权限,否则可能无效。\n是否继续尝试启动?"):
- return
- if self._start_hotkeys():
- self.active = True
- self.start_btn.config(state="disabled")
- self.stop_btn.config(state="normal")
- self.status_label.config(text="状态:已启动(老板键生效)")
- self.save_config()
- logger.info("老板键已启动")
- else:
- if not self.is_admin():
- if messagebox.askyesno("需要管理员权限",
- "注册全局热键失败。是否以管理员身份重新启动程序?"):
- self.save_config()
- self.run_as_admin()
- self.root.destroy()
- sys.exit(0)
- else:
- messagebox.showinfo("取消", "老板键未启动。")
- else:
- messagebox.showerror("错误", "热键注册失败,请检查快捷键是否被占用。")
- def stop(self):
- self.action_queue.put(("stop",))
- self.status_label.config(text="状态:已停止")
- def on_closing(self):
- if self.active:
- self._stop_hotkeys()
- logger.info("程序退出")
- self.root.destroy()
- # ---------------------- 快捷键捕获与队列 ----------------------
- def capture_hotkey(self, var):
- def _capture():
- try:
- self.action_queue.put(("status", "请按下组合键..."))
- hotkey_str = keyboard.read_hotkey(suppress=False)
- self.action_queue.put(("update_hotkey", var, hotkey_str))
- logger.info(f"捕获快捷键: {hotkey_str}")
- except Exception as e:
- self.action_queue.put(("status", f"捕获失败: {e}"))
- logger.error(f"捕获快捷键失败: {e}")
- threading.Thread(target=_capture, daemon=True).start()
- def process_queue(self):
- try:
- while True:
- cmd = self.action_queue.get_nowait()
- if cmd[0] == "status":
- self.status_label.config(text=cmd[1])
- elif cmd[0] == "update_hotkey":
- _, var, value = cmd
- var.set(value)
- elif cmd[0] == "toggle_item":
- item = cmd[1]
- self.toggle_by_item(item)
- elif cmd[0] == "stop":
- self._stop_hotkeys()
- except queue.Empty:
- pass
- self.root.after(100, self.process_queue)
- # ---------------------- 配置持久化 ----------------------
- def save_config(self):
- data = [item.to_dict() for item in self.config_items]
- try:
- with open(CONFIG_FILE, "w", encoding="utf-8") as f:
- json.dump(data, f, ensure_ascii=False, indent=2)
- logger.debug("配置已保存")
- except Exception as e:
- logger.error(f"保存配置失败: {e}")
- def load_config(self):
- if os.path.exists(CONFIG_FILE):
- try:
- with open(CONFIG_FILE, "r", encoding="utf-8") as f:
- data = json.load(f)
- if isinstance(data, list):
- for item_data in data:
- self.config_items.append(HideConfigItem.from_dict(item_data))
- else:
- # 兼容旧版单个配置
- logger.info("检测到旧版配置,正在转换...")
- old = data
- if old.get("enable_self"):
- self.config_items.append(HideConfigItem(
- enable=True, hide_type=HideConfigItem.HIDE_SELF,
- hotkey=old.get("self_hotkey", "ctrl+shift+f9")
- ))
- if old.get("enable_topmost"):
- self.config_items.append(HideConfigItem(
- enable=True, hide_type=HideConfigItem.HIDE_TOPMOST,
- hotkey=old.get("topmost_hotkey", "ctrl+shift+f11")
- ))
- if old.get("enable_target"):
- self.config_items.append(HideConfigItem(
- enable=True, hide_type=HideConfigItem.HIDE_TARGET,
- hotkey=old.get("target_hotkey", "ctrl+shift+f10"),
- target_title=old.get("target_title", "")
- ))
- logger.info("已加载历史配置")
- except Exception as e:
- logger.error(f"加载配置失败: {e}")
- # ---------------------- 主入口 ----------------------
- if __name__ == "__main__":
- auto_mode = "--elevated" in sys.argv
- root = tk.Tk()
- app = BossKeyApp(root, auto_start=auto_mode)
- root.mainloop()
复制代码
收藏
扫描二维码,在手机上阅读
评论一下?