摸鱼小程序-----窗口透明化小程序!!!
Goof off 是一款基于 Python 的窗口透明化工具,允许用户通过简单的操作调整任意窗口的透明度。该工具提供了以下功能:
- 窗口选择与透明度调整:用户可以从窗口列表中选择目标窗口,并通过滑动条或快捷键实时调整其透明度。
- 快捷键支持:支持多种快捷键操作,如增加/减少透明度、回退到上一次透明度、设置为完全透明或完全不透明等。
- 窗口列表刷新:可随时刷新窗口列表,获取最新打开的窗口信息。
- 快捷键说明弹窗:提供快捷键功能说明,方便用户快速掌握操作。
技术实现:该工具使用 tkinter
构建 GUI 界面,结合 win32gui
和 win32con
实现窗口透明化功能。通过树形控件展示窗口列表,支持快捷键绑定
效果图如下:
程序链接:
链接:https://pan.baidu.com/s/1ClJGba4cbXTekEcHw6mALQ?pwd=90ly
提取码: 90ly
代码如下:
import tkinter as tk
from tkinter import ttk
import win32gui
import win32con
""" 说明
1.添加Ctrl 快捷键功能
Ctrl + 增加透明值,设置步长为5
Ctrl - 降低透明值,同上
Ctrl z 回退到上次透明值
Ctrl x 透明值为0
Ctrl d 透明值为100
2.增加Goof off最小化悬浮窗口,达到即使Goof off界面最小化后,也能进行快捷键操作(舍弃方案,技术不足,同时该功能作用不大)
3.在Goof off 界面增加视图框,点击可查看快捷键功能
"""
class RealTimeTransparencyTool:
def __init__(self, root):
self.root = root
self.root.title("Goof off")
self.root.geometry("600x400")
self.selected_hwnd = None # 存储选中的窗口句柄
self.transparency_history = [100] # 透明度历史记录(初始为默认值100%)
self.shortcut_window = None # 快捷视图弹窗变量
self.style_initialized = False # 样式初始化标记(新增)
# 带滚动条的窗口列表容器
tree_frame = ttk.Frame(root)
tree_frame.pack(padx=10, pady=5, fill=tk.BOTH, expand=True)
self.yscroll = ttk.Scrollbar(tree_frame, orient=tk.VERTICAL)
self.yscroll.pack(side=tk.RIGHT, fill=tk.Y)
self.xscroll = ttk.Scrollbar(tree_frame, orient=tk.HORIZONTAL)
self.xscroll.pack(side=tk.BOTTOM, fill=tk.X)
self.tree = ttk.Treeview(
tree_frame,
columns=("hwnd", "title"),
show="headings",
yscrollcommand=self.yscroll.set,
xscrollcommand=self.xscroll.set,
selectmode="browse"
)
self.tree.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
self.yscroll.config(command=self.tree.yview)
self.xscroll.config(command=self.tree.xview)
self.tree.heading("hwnd", text="窗口句柄")
self.tree.heading("title", text="窗口标题")
self.tree.column("hwnd", width=120, anchor="center")
self.tree.column("title", width=600, minwidth=200)
# 快捷键触发标签
self.shortcut_trigger = ttk.Label(
root,
text="查看快捷键 →",
cursor="hand2",
foreground="#2D68FE",
font=("微软雅黑", 9)
)
self.shortcut_trigger.pack(pady=2, padx=10, anchor="w")
self.shortcut_trigger.bind("<Button-1>", self.toggle_shortcut_popup)
# 控制面板布局
control_frame = ttk.Frame(root)
control_frame.pack(padx=10, pady=5, fill=tk.X)
self.transparency_scale = ttk.Scale(
control_frame,
from_=0, to=100,
orient=tk.HORIZONTAL,
command=self.on_scale_changed
)
self.transparency_scale.set(100)
self.transparency_scale.pack(side=tk.LEFT, padx=10, fill=tk.X, expand=True)
self.refresh_btn = ttk.Button(control_frame, text="刷新窗口列表", command=self.refresh_window_list)
self.refresh_btn.pack(side=tk.LEFT, padx=10)
self.status_label = ttk.Label(
root,
text="请选择窗口后拖动滑块/使用快捷键调整透明度(Ctrl+/-调整,Ctrl+Z回退,Ctrl+X/D设为0/100%)",
foreground="#666",
font=("微软雅黑", 9)
)
self.status_label.pack(pady=5)
self.refresh_window_list()
self.tree.bind("<<TreeviewSelect>>", self.on_window_selected)
self.root.bind('<Control-KeyPress>', self.handle_control_shortcut)
# ------------------- 弹窗逻辑-------------------
def toggle_shortcut_popup(self, event):
"""点击触发标签时,切换快捷视图弹窗的显示/隐藏"""
if self.shortcut_window and self.shortcut_window.winfo_exists():
self.shortcut_window.destroy()
self.shortcut_trigger.config(text="查看快捷键 →")
self.shortcut_window = None
else:
# 创建新弹窗(增大尺寸)
self.shortcut_window = tk.Toplevel(self.root)
self.shortcut_window.title("Goof off 快捷键说明")
self.shortcut_window.geometry("380x280") # 优化尺寸
self.shortcut_window.wm_attributes("-topmost", True)
# 居中显示(基于主窗口位置)
x = self.root.winfo_x() + (self.root.winfo_width() - 380) // 2
y = self.root.winfo_y() + (self.root.winfo_height() - 280) // 2
self.shortcut_window.geometry(f"+{x}+{y}")
# 标题样式 有点重复冗余,去掉
# ttk.Label(
# self.shortcut_window,
# text="Goof off 快捷键说明",
# font=("微软雅黑", 12, "bold"),
# foreground="#2D68FE"
# ).pack(pady=10)
# 内容容器(增加内边距)
content_frame = ttk.Frame(self.shortcut_window, padding=10)
content_frame.pack(fill=tk.BOTH, expand=True)
# 快捷功能列表(分两行显示)
shortcuts = [
("Ctrl+加号(+)", "增加透明度(步长为5)"),
("Ctrl+减号(-)", "降低透明度(步长为5)"),
("Ctrl+Z", "回退"),
("Ctrl+X", "完全透明"),
("Ctrl+D", "完全不透明")
]
for key, desc in shortcuts:
# 快捷键标题(加粗)
ttk.Label(
content_frame,
text=f"▸ {key}",
font=("微软雅黑", 10, "bold"),
justify="left"
).pack(pady=2, anchor="w")
# 功能描述(自动换行)
ttk.Label(
content_frame,
text=f" {desc}",
font=("微软雅黑", 9),
wraplength=320, # 限制宽度自动换行
justify="left"
).pack(pady=2, padx=15, anchor="w")
# 关闭按钮(蓝色强调样式)
ttk.Button(
self.shortcut_window,
text="关闭说明",
style="Accent.TButton",
command=lambda: [self.shortcut_window.destroy(), self.shortcut_trigger.config(text="查看快捷键 →")]
).pack(pady=10)
# 初始化按钮样式(仅执行一次)
if not self.style_initialized:
style = ttk.Style()
style.configure("Accent.TButton",
background="#2D68FE",
foreground="white",
padding=(10, 5))
self.style_initialized = True
self.shortcut_trigger.config(text="隐藏快捷键 ←")
# ------------------- 调整透明度主逻辑 -------------------
def get_visible_windows(self):
windows = []
def callback(hwnd, _):
if win32gui.IsWindowVisible(hwnd) and win32gui.GetWindowTextLength(hwnd) > 0:
title = win32gui.GetWindowText(hwnd)
if title != self.root.title():
windows.append((hwnd, title))
return True
win32gui.EnumWindows(callback, None)
return windows
def refresh_window_list(self):
for item in self.tree.get_children():
self.tree.delete(item)
windows = self.get_visible_windows()
for hwnd, title in windows:
self.tree.insert("", tk.END, values=(hwnd, title))
self.status_label.config(text=f"已加载 {len(windows)} 个可见窗口", foreground="green")
def on_window_selected(self, event):
selected = self.tree.selection()
if selected:
self.selected_hwnd = int(self.tree.item(selected[0])["values"][0])
current_alpha = self.transparency_scale.get()
self.status_label.config(
text=f"已选中窗口({win32gui.GetWindowText(self.selected_hwnd)}),当前透明度:{current_alpha}%",
foreground="#333"
)
else:
self.selected_hwnd = None
self.status_label.config(text="请选择窗口后拖动滑块调整透明度", foreground="#666")
def on_scale_changed(self, value):
if not self.selected_hwnd:
self.status_label.config(text="请先选择一个窗口!", foreground="red")
return
try:
transparency = int(float(value) * 2.55)
current_value = float(value)
if not self.transparency_history or self.transparency_history[-1] != current_value:
self.transparency_history.append(current_value)
if not win32gui.IsWindow(self.selected_hwnd):
self.status_label.config(text="目标窗口已关闭,请刷新列表", foreground="red")
self.selected_hwnd = None
return
ex_style = win32gui.GetWindowLong(self.selected_hwnd, win32con.GWL_EXSTYLE)
if not (ex_style & win32con.WS_EX_LAYERED):
win32gui.SetWindowLong(
self.selected_hwnd,
win32con.GWL_EXSTYLE,
ex_style | win32con.WS_EX_LAYERED
)
win32gui.SetLayeredWindowAttributes(
self.selected_hwnd,
0,
transparency,
win32con.LWA_ALPHA
)
self.status_label.config(text=f"实时调整中:透明度 {value}%", foreground="blue")
except Exception as e:
self.status_label.config(text=f"调整失败: {str(e)}", foreground="red")
def handle_control_shortcut(self, event):
if not self.selected_hwnd:
self.status_label.config(text="请先选择一个窗口!", foreground="red")
return
current_value = self.transparency_scale.get()
new_value = current_value
if event.keysym in ('plus', 'equal'):
new_value = min(current_value + 5, 100)
elif event.keysym == 'minus':
new_value = max(current_value - 5, 0)
elif event.keysym == 'z':
if len(self.transparency_history) > 1:
self.transparency_history.pop()
new_value = self.transparency_history[-1]
else:
self.status_label.config(text="无更多历史记录", foreground="orange")
return
elif event.keysym == 'x':
new_value = 0
elif event.keysym == 'd':
new_value = 100
else:
return
self.transparency_scale.set(new_value)
self.status_label.config(text=f"快捷键调整:透明度 {new_value}%", foreground="purple")
if __name__ == "__main__":
root = tk.Tk()
app = RealTimeTransparencyTool(root)
root.mainloop()