【问题标题】:Python Window ActivationPython 窗口激活
【发布时间】:2010-01-19 01:25:50
【问题描述】:

如何使用 Python 以编程方式激活 Windows 中的窗口?我正在向它发送击键,目前我只是确保它是最后使用的应用程序,然后发送击键 Alt+Tab 以从 DOS 控制台切换到它。有没有更好的方法(因为我通过经验了解到这种方法绝不是万无一失的)?

【问题讨论】:

  • 您真的应该告诉我们您使用的是什么 GUI 工具包,因为工具包中可能包含此功能。
  • 也许他只是想激活任何一个打开的窗口?

标签: python windows


【解决方案1】:

您可以使用 win32gui 模块来执行此操作。首先,您需要在您的窗口上获得一个有效的句柄。如果您知道窗口类名称或确切的标题,则可以使用win32gui.FindWindow。如果没有,您可以使用win32gui.EnumWindows 枚举窗口并尝试找到正确的窗口。

获得句柄后,您可以使用句柄调用win32gui.SetForegroundWindow。它将激活窗口并准备好获取您的击键。

请参阅下面的示例。希望对你有帮助

import win32gui
import re


class WindowMgr:
    """Encapsulates some calls to the winapi for window management"""

    def __init__ (self):
        """Constructor"""
        self._handle = None

    def find_window(self, class_name, window_name=None):
        """find a window by its class_name"""
        self._handle = win32gui.FindWindow(class_name, window_name)

    def _window_enum_callback(self, hwnd, wildcard):
        """Pass to win32gui.EnumWindows() to check all the opened windows"""
        if re.match(wildcard, str(win32gui.GetWindowText(hwnd))) is not None:
            self._handle = hwnd

    def find_window_wildcard(self, wildcard):
        """find a window whose title matches the wildcard regex"""
        self._handle = None
        win32gui.EnumWindows(self._window_enum_callback, wildcard)

    def set_foreground(self):
        """put the window in the foreground"""
        win32gui.SetForegroundWindow(self._handle)


w = WindowMgr()
w.find_window_wildcard(".*Hello.*")
w.set_foreground()

【讨论】:

  • 当您同时打开同一个应用程序的多个实例时,这不起作用,因为您无法区分它们(因为它全部基于窗口标题) .真可惜,但我想这是 Win32API 而不是这个特定的 python 模块?
  • hwnd 代表什么? (嘘缩写!)
  • @NullVoxPopuli 手是窗户上的把手。这个缩写一般用在windows win32 api中
  • 2018-11-26。我在 Windows 10 上使用 pip 18.0.1 安装 win32gui 时收到ModuleNotFoundError: No module named 'win32.distutils.command'
  • 在某些 Windows 版本上,SetForegroundWindow 可能会导致意外错误。要修复,您需要先发送一个 alt 键,更多 info
【解决方案2】:

PywinautoSWAPY 可能需要最少的努力 to set the focus of a window

使用 SWAPY 自动生成检索窗口对象所需的 python 代码,例如:

import pywinauto

# SWAPY will record the title and class of the window you want activated
app = pywinauto.application.Application()
t, c = u'WINDOW SWAPY RECORDS', u'CLASS SWAPY RECORDS'
handle = pywinauto.findwindows.find_windows(title=t, class_name=c)[0]
# SWAPY will also get the window
window = app.window_(handle=handle)

# this here is the only line of code you actually write (SWAPY recorded the rest)
window.SetFocus()

如果偶然有其他窗口位于感兴趣的窗口前面,则不是问题。 This additional codethis 将确保在运行上述代码之前显示它:

# minimize then maximize to bring this window in front of all others
window.Minimize()
window.Maximize()
# now you can set its focus
window.SetFocus()

【讨论】:

  • 这个例子一直给我一个错误,即第 6 行的列表索引超出范围(初始化句柄的那个)。我试图查找 pywinauto.findwindows.find_windows() 方法的信息,但文档中没有。
  • 注意:在安装之前运行的任何python shell必须在使用pywinautogui之前重新启动,否则在加载时会丢失一个依赖项; Pywinauto 不能热插拔。
  • 感谢最小化最大化技巧。它还使用 win32gui 解决了我的问题
【解决方案3】:
import ctypes, platform

if platform.system() == 'Windows':
    Active_W = ctypes.windll.user32.GetActiveWindow()
    ctypes.windll.user32.SetWindowPos(Active_W,0,0,0,0,0,0x0002|0x0001)

我们开始吧。您只需要存储活动窗口的值。

【讨论】:

    【解决方案4】:

    Pip 安装键盘。 在设置前台窗口之前,模拟一个键盘到 esc 即 keyboard.send('esc') 对于以下任一情况,您可能需要执行 3 次:

    1. 侧边栏
    2. Windows 键覆盖
    3. 始终位于顶部的任务管理器

    【讨论】:

    • 我在 Windows 环境中开发,因为...很多:) 我应该习惯于面对荒谬的问题。尽管如此,当有一件事情发生时,我仍然感到惊讶。感谢您的建议,看来它拯救了我的一天!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-09
    • 2021-08-06
    • 2018-04-19
    • 2016-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多