如何用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
相关产品推荐
相关产品推荐

