关注终端

Keeping the terminal in focus

我有一个 python 脚本,它使用 selenium 来自动化网页,将焦点从需要用户输入的终端上移开。

在 python 中是否有以编程方式将焦点切换回终端?

我将 运行 我的程序 Windows 命令提示符 Windows 7,如果重要的话,但跨平台的答案将是最有用的。


尝试次数

查看 win32 的 pywin32 包绑定 API 我有以下内容:

import win32console
import win32gui
from selenium import webdriver as wd

d = wd.Firefox()
win32gui.SetFocus(win32console.GetConsoleWindow())
win32gui.FlashWindow(win32console.GetConsoleWindow(), False)
input('Should have focus: ')

SetFocus 导致错误 pywintypes.error: (5, 'SetFocus', 'Access is denied.') 由于 Microsoft 删除了从另一个应用程序获取焦点的能力。

FlashWindow 似乎什么也没做。

这并没有真正回答你的问题,但简单的解决办法是一开始就不要把焦点移开:

driver = webdriver.PhantomJS()
# ...

PhantomJS webdriver 没有任何 UI,所以不会抢走焦点。

要获得焦点,请查看对 this answer 的评论。

一种跨平台的方法可能是将 Tkinter 用于用户 GUI,因为它具有为其 windows.

抓取和设置焦点的方法

这是我想出的方法,似乎有效。

class WindowManager:
    def __init__(self):
        self._handle = None

    def _window_enum_callback( self, hwnd, wildcard ):
        if re.match(wildcard, str(win32gui.GetWindowText(hwnd))) != None:
            self._handle = hwnd

    #CASE SENSITIVE
    def find_window_wildcard(self, wildcard):
        self._handle = None
        win32gui.EnumWindows(self._window_enum_callback, wildcard)

    def set_foreground(self):
        win32gui.ShowWindow(self._handle, win32con.SW_RESTORE)
        win32gui.SetWindowPos(self._handle,win32con.HWND_NOTOPMOST, 0, 0, 0, 0, win32con.SWP_NOMOVE + win32con.SWP_NOSIZE)  
        win32gui.SetWindowPos(self._handle,win32con.HWND_TOPMOST, 0, 0, 0, 0, win32con.SWP_NOMOVE + win32con.SWP_NOSIZE)  
        win32gui.SetWindowPos(self._handle,win32con.HWND_NOTOPMOST, 0, 0, 0, 0, win32con.SWP_SHOWWINDOW + win32con.SWP_NOMOVE + win32con.SWP_NOSIZE)
        shell = win32com.client.Dispatch("WScript.Shell")
        shell.SendKeys('%')
        win32gui.SetForegroundWindow(self._handle)

    def find_and_set(self, search):
        self.find_window_wildcard(search)
        self.set_foreground()

然后找到一个 window 并激活它你可以...

w = WindowManager()
w.find_and_set(".*cmd.exe*")

这是在 python 2.7 中,这里还有一些我找到的链接来解释为什么你必须经历这么多麻烦才能切换到活动状态 windows。

win32gui.SetActiveWindow() ERROR : The specified procedure could not be found

Windows 7: how to bring a window to the front no matter what other window has focus?

如果您不关心清除 matplotlib 框架中显示的任何图形——我相信当人们想要将焦点重新放在控制台上以供用户输入时通常是这种情况——只需使用这个:

plt.close("all")