Linux下如何用Python默认模块获取当前聚焦窗口名称
在Linux上获取当前聚焦窗口名称的替代方案(无需Xlib)
嘿,完全理解你不想碰Xlib的想法!在Linux上获取当前聚焦窗口的名称,其实有几个更接地气的方法——借助现成的命令行工具,Python脚本直接调用它们就行,不用跟复杂的X11 API打交道。下面给你介绍几个靠谱的方案:
方法1:使用xdotool
xdotool是一个专门用于模拟X11键盘鼠标操作、查询窗口信息的工具,用法非常直观。
步骤:
- 先安装xdotool(以Debian/Ubuntu为例):
sudo apt install xdotool
- 在Python中调用它获取窗口名称:
import subprocess def get_active_window_name(): try: # 调用xdotool获取活动窗口的名称 window_name = subprocess.check_output( ["xdotool", "getactivewindow", "getwindowname"], text=True ).strip() return window_name except subprocess.CalledProcessError: return "无法获取当前窗口名称" # 测试一下 if __name__ == "__main__": print("当前聚焦窗口:", get_active_window_name())
这个方法的优点是代码简洁,几乎不需要额外处理,xdotool直接返回窗口名称字符串。
方法2:使用xprop
xprop是X11自带的属性查看工具,可以查询窗口的各种属性信息,包括窗口名称。
步骤:
- xprop一般是X11默认安装的,不用额外装。
- Python调用代码:
import subprocess import re def get_active_window_name(): try: # 第一步:获取当前活动窗口的ID root_output = subprocess.check_output( ["xprop", "-root", "_NET_ACTIVE_WINDOW"], text=True ) # 从输出中提取窗口ID(格式是0x开头的十六进制) window_id = re.search(r'0x[0-9a-fA-F]+', root_output).group() # 第二步:根据窗口ID获取窗口名称 window_prop = subprocess.check_output( ["xprop", "-id", window_id, "WM_NAME"], text=True ) # 提取名称部分(兼容UTF8_STRING和STRING两种格式) name_match = re.search(r'WM_NAME\(.*?\) = "(.*?)"', window_prop) if name_match: return name_match.group(1) return "无法解析窗口名称" except (subprocess.CalledProcessError, AttributeError): return "无法获取当前窗口名称" # 测试 if __name__ == "__main__": print("当前聚焦窗口:", get_active_window_name())
这个方法依赖X11的标准属性,兼容性很好,几乎所有X11桌面都支持。
方法3:使用wmctrl
wmctrl是一个窗口管理器控制工具,可以列出所有窗口、切换窗口,也能找到当前活动窗口的信息。
步骤:
- 安装wmctrl:
sudo apt install wmctrl
- Python调用代码:
import subprocess import re def get_active_window_name(): try: # 获取当前活动窗口的PID pid_output = subprocess.check_output( ["xprop", "-root", "_NET_ACTIVE_WINDOW_PID"], text=True ) window_pid = re.search(r'\d+', pid_output).group() # 列出所有窗口,找到对应PID的那一行 window_list = subprocess.check_output( ["wmctrl", "-l", "-p"], text=True ).splitlines() for line in window_list: if window_pid in line: # 窗口名称从第5列开始,拼接起来返回 return ' '.join(line.split()[4:]) return "未找到对应窗口" except (subprocess.CalledProcessError, AttributeError): return "无法获取当前窗口名称" # 测试 if __name__ == "__main__": print("当前聚焦窗口:", get_active_window_name())
这个方法通过PID关联窗口,有时候能避免窗口ID变化带来的问题。
补充:Wayland环境下的方案
如果你的Linux桌面用的是Wayland(比如GNOME 40+、Sway等),上面的X11工具就失效了,推荐用下面的方法:
GNOME Wayland环境:
import subprocess import json def get_active_window_name(): try: # 调用gdbus查询GNOME Shell的当前窗口标题 result = subprocess.check_output( [ "gdbus", "call", "--session", "--dest", "org.gnome.Shell", "--object-path", "/org/gnome/Shell", "--method", "org.gnome.Shell.Eval", "global.display.get_current_window().get_title()" ], text=True ) # 解析返回的结果(格式类似 (true, '"窗口名称"')) output = json.loads(result.split(',')[1].strip()) return output except subprocess.CalledProcessError: return "无法获取当前窗口名称" # 测试 if __name__ == "__main__": print("当前聚焦窗口:", get_active_window_name())
Sway Wayland环境:
import subprocess import json def get_active_window_name(): try: # 调用swaymsg获取窗口树信息 tree_output = subprocess.check_output( ["swaymsg", "-t", "get_tree"], text=True ) tree = json.loads(tree_output) # 递归查找focused为true的窗口 def find_focused(node): if node.get("focused"): return node.get("name") for child in node.get("nodes", []) + node.get("floating_nodes", []): result = find_focused(child) if result: return result return None return find_focused(tree) or "无法获取当前窗口名称" except subprocess.CalledProcessError: return "无法获取当前窗口名称" # 测试 if __name__ == "__main__": print("当前聚焦窗口:", get_active_window_name())
内容的提问来源于stack exchange,提问作者user7659542
相关产品推荐
相关产品推荐

