Keeping the terminal in focus

故事扮演 提交于 2019-12-09 09:49:44

问题


I have a python script which uses selenium to automate web page, drawing focus away from the terminal where user input is required.

Is there anyway in python to switch focus back to the terminal, programmatically?

I will be running my program in the Windows Command Prompt on Windows 7, if it matters, but a cross platform answer would be most useful.


Attempts

Looking at the pywin32 package bindings for the win32 API I have the following:

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 causes the error pywintypes.error: (5, 'SetFocus', 'Access is denied.') due to Microsoft removing the ability to take focus from another application.

FlashWindow appears to do nothing.


回答1:


Here is what I came up with that seems to be working.

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()

Then to find a window and make it active you can...

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

This is in python 2.7, also here are some links I found to explain why you have to go through so much trouble to switch active 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?




回答2:


This doesn't really answer your question, but the easy solution is to not take the focus away in the first place:

driver = webdriver.PhantomJS()
# ...

The PhantomJS webdriver doesn't have any UI, so does not steal the focus.




回答3:


For getting focus, check the comments to this answer.

A cross-platform method could be to use Tkinter for the user GUI, as it has methods to grab and set focus for its windows.




回答4:


If you don't care about clearing any figure displayed in the matplotlib frame -- which I believe is normally the case when one wants to get the focus back on the console for user input -- use simply this:

plt.close("all")


来源:https://stackoverflow.com/questions/30512267/keeping-the-terminal-in-focus

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!