Ubuntu Gnome 16.04下如何用Tkinter将窗口置于所有窗口底层?
如何在Ubuntu GNOME 16.04中将Tkinter窗口置于所有窗口底层(Super+D可见)
好问题!Tkinter本身并没有原生支持将窗口置于所有其他窗口底层的API,因为它的跨平台设计没有暴露这种系统级的窗口层级控制。不过在Ubuntu GNOME 16.04(基于X11)的环境下,我们有两种可靠的方法来实现这个需求——让窗口留在底层,并且按下Super+D(也就是你提到的Win+D)显示桌面时依然可见。
方案1:使用wmctrl命令行工具(简单易上手)
wmctrl是一款X11窗口管理工具,可以通过命令行控制窗口的层级和属性。Ubuntu默认可能没有预装,先通过以下命令安装:
sudo apt-get install wmctrl
接下来是实现代码,核心思路是先创建Tkinter窗口,再通过wmctrl找到它的窗口ID,然后设置它为底层窗口并标记为"sticky"(这样Super+D时不会被隐藏):
import tkinter as tk import subprocess import time root = tk.Tk() root.title("桌面底层窗口") root.geometry("400x300") # 短暂等待,确保窗口完全创建后再获取ID time.sleep(0.1) # 通过窗口标题匹配获取窗口ID window_title = "桌面底层窗口" wmctrl_output = subprocess.check_output(["wmctrl", "-l"]).decode("utf-8") window_id = None for line in wmctrl_output.splitlines(): if window_title in line: window_id = line.split()[0] break if window_id: # 将窗口设置为底层,同时添加sticky属性(Super+D时保留) subprocess.run(["wmctrl", "-i", "-r", window_id, "-b", "add,below,sticky"]) # 可选:让窗口不在任务栏和窗口切换器中显示,更贴近桌面组件 subprocess.run(["wmctrl", "-i", "-r", window_id, "-b", "add,skip_taskbar,skip_pager"]) root.mainloop()
关键参数解释:
-b add,below:将窗口添加到所有其他窗口的底层-b add,sticky:标记窗口为"粘性",确保Super+D显示桌面时不会被隐藏skip_taskbar/skip_pager:让窗口不在任务栏和Alt+Tab切换器中出现,避免干扰正常操作
方案2:使用Python的Xlib库直接操作X11(无外部依赖)
如果你不想依赖外部命令行工具,可以用python3-xlib直接和X11窗口系统交互,这是更底层的实现方式。先安装库:
sudo apt-get install python3-xlib
代码示例如下:
import tkinter as tk from Xlib import X, display root = tk.Tk() root.title("X11底层窗口") root.geometry("400x300") # 获取X11显示对象和当前Tkinter窗口的X11句柄 d = display.Display() tk_win_id = root.winfo_id() x11_win = d.create_resource_object('window', tk_win_id) # 1. 将窗口置于所有窗口底层 x11_win.configure(stack_mode=X.Below) # 2. 设置窗口为sticky,确保Super+D时不被隐藏 wm_hints = x11_win.get_wm_hints() wm_hints.flags |= X.StateHint wm_hints.state = X.NormalState | X.StickyState x11_win.set_wm_hints(wm_hints) # 3. 让窗口不在任务栏和切换器中显示 atom_skip_taskbar = d.intern_atom("_NET_WM_STATE_SKIP_TASKBAR") atom_skip_pager = d.intern_atom("_NET_WM_STATE_SKIP_PAGER") x11_win.change_property( d.intern_atom("_NET_WM_STATE"), X.ATOM, 32, [atom_skip_taskbar, atom_skip_pager] ) # 同步所有X11操作到系统 d.sync() root.mainloop()
核心逻辑说明:
stack_mode=X.Below:直接通过X11 API将窗口层级设置为底层StickyState:给窗口添加粘性属性,使其在显示桌面时保持可见_NET_WM_STATE_SKIP_TASKBAR/_NET_WM_STATE_SKIP_PAGER:通过X11属性让窗口跳过任务栏和切换器
注意事项
- 在Ubuntu GNOME 16.04中,Super+D的核心行为是隐藏所有非
sticky的窗口,所以必须设置sticky属性才能让窗口在显示桌面时保留。 - 方案1的
wmctrl更适合快速实现,代码逻辑简单;方案2的Xlib更灵活,适合需要深度定制窗口行为的场景。 - 如果使用窗口标题匹配,确保你的窗口标题是唯一的,避免
wmctrl匹配到错误的窗口。
内容的提问来源于stack exchange,提问作者Guy
相关产品推荐
相关产品推荐

