如何在Linux的Tkinter窗口设置非Alpha模式的透明背景?
在Linux(Ubuntu)中用Tkinter实现窗口背景透明但控件不透明的方法?
我已经在Windows和macOS系统中实现了Tkinter窗口部分区域透明的效果,具体方法如下:
Windows系统实现代码
root.attributes("-transparentcolor", '#000001') root.config(bg="#000001")
macOS系统实现代码
root.attributes("-transparent", True) root.config(bg="systemTransparent")
但在Linux(Ubuntu)系统中,上述方法均无效——该系统下Tkinter没有transparent相关属性。同时我不想使用-alpha属性,因为它会让整个窗口(包括控件)都变得透明,我需要的是窗口背景完全透明,而其他控件保持可见/不透明。
Windows和macOS下的效果示例


在Linux(Ubuntu)系统中可以实现这个需求,核心思路是利用X11的窗口形状(shape)功能,或者部分版本支持的-transparentcolor属性来实现,以下是两种可行方法:
方法一:尝试使用-transparentcolor属性(部分Tk版本支持)
部分Linux发行版的Tkinter编译时加入了对-transparentcolor的支持,直接复用Windows的逻辑即可尝试:
import tkinter as tk root = tk.Tk() root.attributes("-transparentcolor", "#000001") root.config(bg="#000001") # 添加测试控件 test_btn = tk.Button(root, text="测试按钮") test_btn.pack(padx=20, pady=20) root.mainloop()
方法二:使用X11 Shape功能(更可靠)
如果方法一无效,可借助Tkinter的shape扩展(需确保系统安装了python3-tk依赖),通过手动裁剪窗口可见区域,只保留控件所在部分:
import tkinter as tk from tkinter import ttk root = tk.Tk() root.overrideredirect(True) # 可选:移除窗口边框,若需要边框可删除此行 root.attributes("-topmost", True) # 可选:设置窗口置顶 # 创建占位画布(后续会被裁剪隐藏) canvas = tk.Canvas(root, bg="#000000", highlightthickness=0) canvas.pack(fill="both", expand=True) # 添加示例控件 btn = ttk.Button(root, text="测试按钮") btn.place(x=20, y=20) label = ttk.Label(root, text="测试标签", background="#ffffff") label.place(x=20, y=60) # 更新窗口可见区域的函数 def update_window_shape(): root.update_idletasks() visible_regions = [] # 遍历所有控件,收集它们的边界框 for widget in root.winfo_children(): if widget != canvas: x = widget.winfo_x() y = widget.winfo_y() width = widget.winfo_width() height = widget.winfo_height() visible_regions.append((x, y, x + width, y + height)) # 设置窗口可见形状 if visible_regions: # 初始化第一个区域 root.shape_rectangle(*visible_regions[0]) # 合并后续区域 for region in visible_regions[1:]: root.shape_rectangle(*region, "union") else: # 无控件时隐藏整个窗口 root.shape_rectangle(0, 0, 0, 0) # 初始化形状并绑定窗口变化事件 update_window_shape() root.bind("<Configure>", lambda _: update_window_shape()) root.mainloop()
注意事项
- 如果保留窗口边框(删除
overrideredirect(True)),需要调整控件坐标的计算,加入窗口边框的偏移量(可通过root.winfo_rootx() - root.winfo_x()获取水平偏移)。 - 若控件动态变化(比如新增、移动、改变大小),需要重新调用
update_window_shape()来更新可见区域。
内容的提问来源于stack exchange,提问作者Akascape
相关产品推荐
相关产品推荐

