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

如何在Wayland环境下使用Python捕获任意窗口的截图?

在Wayland环境下实现PyQt5区域截图的解决方案

Wayland的安全机制禁止应用直接捕获其他窗口内容,导致X11下可用的mss或Qt原生grabWindow方法无法正常工作。以下是几种可行的Python实现方案:

方案一:通过DBus调用GNOME Shell截图服务(GNOME Wayland专属)

适用于GNOME桌面的Wayland环境,直接通过DBus调用系统内置截图服务,无需依赖外部命令,且会触发系统权限授权流程。

首先安装依赖库:

pip install dbus-python pillow

实现代码:

import dbus
from PIL import Image
import io

def take_wayland_screenshot(self, x1, y1, x2, y2):
    # 修正坐标顺序,确保x1<x2、y1<y2
    x1, x2 = min(x1, x2), max(x1, x2)
    y1, y2 = min(y1, y2), max(y1, y2)
    width = x2 - x1
    height = y2 - y1

    # 连接到GNOME Shell截图DBus服务
    bus = dbus.SessionBus()
    screenshot_obj = bus.get_object(
        'org.gnome.Shell.Screenshot',
        '/org/gnome/Shell/Screenshot'
    )
    screenshot_iface = dbus.Interface(screenshot_obj, 'org.gnome.Shell.Screenshot')

    # 调用区域截图接口,返回截图字节数据
    success, img_data = screenshot_iface.ScreenshotArea(x1, y1, width, height, False)
    if success:
        # 转换为PIL图片并保存
        img = Image.open(io.BytesIO(img_data))
        img.save("screenshot.png")
        print("Screenshot saved as screenshot.png")
    else:
        print("Failed to capture screenshot")

方案二:使用pyscreenshot跨平台库

pyscreenshot会自动检测当前环境并选择合适的截图后端(Wayland下会调用系统原生截图工具如gnome-screenshot或grim),无需手动适配环境。

安装依赖:

pip install pyscreenshot

实现代码:

import pyscreenshot as ImageGrab

def take_screenshot(self, x1, y1, x2, y2):
    # 修正坐标顺序
    x1, x2 = min(x1, x2), max(x1, x2)
    y1, y2 = min(y1, y2), max(y1, y2)
    # 截取指定区域
    img = ImageGrab.grab(bbox=(x1, y1, x2, y2))
    img.save("screenshot.png")
    print("Screenshot saved as screenshot.png")

注意:需确保系统已安装对应桌面的截图工具(如GNOME的gnome-screenshot、Sway的grim),否则库会调用失败。

方案三:子进程调用系统截图工具(最终备选)

如果上述方案无法满足需求,可直接调用系统原生截图工具,这是最可靠的兼容方案,但需要处理不同桌面环境的工具差异。

GNOME Wayland环境示例:

import subprocess

def take_screenshot(self, x1, y1, x2, y2):
    x1, x2 = min(x1, x2), max(x1, x2)
    y1, y2 = min(y1, y2), max(y1, y2)
    width = x2 - x1
    height = y2 - y1

    # 调用gnome-screenshot截取指定区域
    subprocess.run([
        "gnome-screenshot",
        "-a",
        "-f", "screenshot.png",
        "--area", f"{x1},{y1},{width},{height}"
    ], check=True)
    print("Screenshot saved as screenshot.png")

Sway等Wayland环境示例(使用grim):

import subprocess

def take_screenshot(self, x1, y1, x2, y2):
    x1, x2 = min(x1, x2), max(x1, x2)
    y1, y2 = min(y1, y2), max(y1, y2)
    # grim的区域格式为x,y WxH
    subprocess.run([
        "grim",
        "-g", f"{x1},{y1} {x2-x1}x{y2-y1}",
        "screenshot.png"
    ], check=True)
    print("Screenshot saved as screenshot.png")

内容的提问来源于stack exchange,提问作者Vanillaice

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 11:24:51