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

如何编写Python脚本准确计算桌面被可见窗口遮挡的百分比?

解决桌面遮挡百分比计算的问题

原代码的核心问题

  1. 窗口筛选错误:使用EnumChildWindows获取桌面子窗口,包含大量非顶层窗口(如按钮、控件、托盘小窗口等),而非真正的顶层应用窗口。
  2. 未排除无效窗口:没有过滤最小化窗口、不可见窗口,以及完全不在桌面区域内的窗口。
  3. 重叠区域重复计算:直接累加所有窗口面积,重叠部分被多次扣除,导致结果远大于实际遮挡比例。

修改后的代码

import win32api
import win32gui
import win32con

def merge_rectangles(rects):
    """合并重叠或相邻的矩形,返回合并后的矩形列表"""
    if not rects:
        return []
    
    # 按左边界排序
    sorted_rects = sorted(rects, key=lambda r: r[0])
    merged = [sorted_rects[0]]
    
    for current in sorted_rects[1:]:
        last = merged[-1]
        # 当前矩形与最后一个合并矩形重叠或相邻
        if current[0] <= last[2] and current[1] <= last[3]:
            # 计算新的合并矩形
            new_left = min(last[0], current[0])
            new_top = min(last[1], current[1])
            new_right = max(last[2], current[2])
            new_bottom = max(last[3], current[3])
            merged[-1] = (new_left, new_top, new_right, new_bottom)
        else:
            merged.append(current)
    
    return merged

def calculate_covered_area(rects):
    """计算矩形列表的总面积(去重重叠部分)"""
    merged_rects = merge_rectangles(rects)
    total = 0
    for rect in merged_rects:
        left, top, right, bottom = rect
        width = right - left
        height = bottom - top
        if width > 0 and height > 0:
            total += width * height
    return total

def get_desktop_covered_percentage():
    # 获取虚拟桌面的尺寸(支持多显示器)
    desktop_left = win32api.GetSystemMetrics(win32con.SM_XVIRTUALSCREEN)
    desktop_top = win32api.GetSystemMetrics(win32con.SM_YVIRTUALSCREEN)
    desktop_width = win32api.GetSystemMetrics(win32con.SM_CXVIRTUALSCREEN)
    desktop_height = win32api.GetSystemMetrics(win32con.SM_CYVIRTUALSCREEN)
    desktop_rect = (desktop_left, desktop_top, desktop_left + desktop_width, desktop_top + desktop_height)
    desktop_area = desktop_width * desktop_height
    if desktop_area == 0:
        return 0.0

    valid_window_rects = []

    def enum_window_callback(hwnd, extra):
        # 筛选条件:
        # 1. 窗口可见
        if not win32gui.IsWindowVisible(hwnd):
            return True
        # 2. 窗口未最小化
        if win32gui.IsIconic(hwnd):
            return True
        # 3. 获取窗口矩形
        rect = win32gui.GetWindowRect(hwnd)
        left, top, right, bottom = rect
        # 4. 窗口有实际大小
        if right <= left or bottom <= top:
            return True
        # 5. 窗口与桌面区域有交集
        if right < desktop_rect[0] or left > desktop_rect[2] or bottom < desktop_rect[1] or top > desktop_rect[3]:
            return True
        # 6. 若不需要统计任务栏,可取消以下注释:
        # if win32gui.GetClassName(hwnd) == "Shell_TrayWnd":
        #     return True
        
        # 裁剪窗口到桌面范围内(避免窗口超出桌面的部分被计算)
        clipped_left = max(left, desktop_rect[0])
        clipped_top = max(top, desktop_rect[1])
        clipped_right = min(right, desktop_rect[2])
        clipped_bottom = min(bottom, desktop_rect[3])
        valid_window_rects.append((clipped_left, clipped_top, clipped_right, clipped_bottom))
        return True

    # 枚举所有顶层窗口
    win32gui.EnumWindows(enum_window_callback, None)

    # 计算所有有效窗口的并集面积
    covered_area = calculate_covered_area(valid_window_rects)
    # 计算遮挡百分比
    percentage = (covered_area / desktop_area) * 100
    # 确保结果在0-100之间
    return max(0.0, min(100.0, percentage))

if __name__ == "__main__":
    percentage = get_desktop_covered_percentage()
    print(f"桌面被窗口遮挡的百分比: {percentage:.2f}%")

关键修改说明

  • 窗口筛选逻辑:使用EnumWindows枚举顶层窗口,通过多条件过滤有效窗口,确保只统计可见、非最小化且与桌面有交集的顶层窗口。
  • 重叠区域处理:实现矩形合并函数,将重叠或相邻的窗口矩形合并,避免重叠部分重复计算,保证面积统计准确。
  • 多显示器适配:使用虚拟屏幕尺寸获取完整桌面范围,同时将窗口矩形裁剪到桌面边界内,避免超出桌面的区域被错误统计。
  • 结果校准:将最终百分比限制在0-100区间,避免计算误差导致的异常值。

内容的提问来源于stack exchange,提问作者Neo-S

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 20:30:43