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

如何用Python获取多显示器各前台应用的日志?

多显示器前台应用日志监控方案

需求概述

需要开发监控Web应用,获取多台显示器各自显示的前台应用日志,预期日志格式示例:

The foreground applications are: views.py - sk-access-control-ai - Visual Studio Code and yGetWindow Docs - Google Chrome

现有代码缺陷

当前基于win32gui的代码会按显示器数量固定返回对应条数的窗口标题,但部分显示器处于桌面(无前台应用)时,仍会生成对应数量的日志,无法匹配实际需求。现有代码如下:

import win32gui
def get_window_titles():
   
    window_titles = []
    try:
       
        def enum_window_titles(hwnd, window_titles):
            if win32gui.IsWindowVisible(hwnd):
                window_title = win32gui.GetWindowText(hwnd)
                if window_title:
                    window_titles.append(window_title)

        win32gui.EnumWindows(enum_window_titles, window_titles)
    except Exception as e:
        print(f"Error getting window titles: {e}")
    return window_titles[:2] # This number is replaced by the number of existing monitors

# Getting and printing window titles
window_titles = get_window_titles()
for title in window_titles:
    print("Foreground applications are: " + title)

解决方案

核心思路是为每个显示器匹配对应的实际前台活动窗口,而非盲目截取固定数量的窗口。具体实现步骤如下:

1. 获取显示器区域信息

先枚举所有显示器的坐标范围,明确每个屏幕的边界。

2. 匹配显示器与前台窗口

判断前台窗口的中心位置是否落在对应显示器区域内,确保窗口属于该显示器。

3. 生成精准日志

仅收集存在有效前台应用的显示器信息,无应用的显示器不生成日志条目。

修改后的完整代码:

import win32gui
import win32api
import win32con

def get_monitors():
    # 枚举所有显示器的位置与分辨率
    monitors = []
    def enum_monitors(hMonitor, hdcMonitor, lprcMonitor, dwData):
        monitors.append((lprcMonitor.left, lprcMonitor.top, lprcMonitor.right, lprcMonitor.bottom))
        return True
    win32api.EnumDisplayMonitors(None, None, enum_monitors, None)
    return monitors

def get_foreground_window_for_monitor(monitor_rect):
    # 获取指定显示器内的前台活动窗口标题
    foreground_hwnd = win32gui.GetForegroundWindow()
    if not foreground_hwnd:
        return None
    
    # 获取窗口的坐标范围
    win_left, win_top, win_right, win_bottom = win32gui.GetWindowRect(foreground_hwnd)
    # 以窗口中心判断所属显示器
    win_center_x = (win_left + win_right) // 2
    win_center_y = (win_top + win_bottom) // 2
    mon_left, mon_top, mon_right, mon_bottom = monitor_rect
    
    if mon_left <= win_center_x <= mon_right and mon_top <= win_center_y <= mon_bottom:
        title = win32gui.GetWindowText(foreground_hwnd)
        return title if title else None
    return None

def get_per_monitor_foreground_apps():
    monitors = get_monitors()
    foreground_apps = []
    
    for monitor in monitors:
        app_title = get_foreground_window_for_monitor(monitor)
        if app_title:
            foreground_apps.append(app_title)
    
    return foreground_apps

# 生成符合预期的日志
apps = get_per_monitor_foreground_apps()
if apps:
    print(f"The foreground applications are: {' and '.join(apps)}")
else:
    print("No foreground applications found on any monitor.")

代码说明

  • get_monitors():调用系统API获取所有显示器的边界坐标,为后续窗口匹配提供依据。
  • get_foreground_window_for_monitor():通过窗口中心位置判断前台窗口是否属于目标显示器,仅返回非空的有效标题。
  • get_per_monitor_foreground_apps():遍历所有显示器,收集存在前台应用的标题列表,自动过滤无应用的显示器。
  • 最终输出的日志仅包含有前台应用的条目,完全符合需求。

内容的提问来源于stack exchange,提问作者André Pimentel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 23:47:45