问题
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