You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:47:13