Window.activate() not working in Jupyter Notebook
DleanJeans opened this issue · 12 comments
Works fine in a cmd
but when I run it on a Jupyter Notebook (Colab local runtime):
import pyautogui
pyautogui.getWindowsWithTitle('Code')[0].activate()
VSCode flashes on the taskbar but never activated.
Strangely if I focus the window first with pywinauto
:
import pywinauto
pywinauto.application.Application().connect(best_match='Code').top_window().set_focus()
then it would work normally, until I restarted the notebook. This only affects one window, other windows have to be focused with pywinauto
before being able to be activated with pygetwindow
.
Kernel output:
---------------------------------------------------------------------------
PyGetWindowException Traceback (most recent call last)
<ipython-input-2-f7654fe7bc43> in <module>()
1
2 import pyautogui
----> 3 pyautogui.getWindowsWithTitle('Code')[0].activate()
c:\users\dleanjeans\appdata\local\programs\python\python36\lib\site-packages\pygetwindow\_pygetwindow_win.py in activate(self)
282 result = ctypes.windll.user32.SetForegroundWindow(self._hWnd)
283 if result == 0:
--> 284 _raiseWithLastError()
285
286
c:\users\dleanjeans\appdata\local\programs\python\python36\lib\site-packages\pygetwindow\_pygetwindow_win.py in _raiseWithLastError()
95 information from GetLastError() and FormatMessage()."""
96 errorCode = ctypes.windll.kernel32.GetLastError()
---> 97 raise pygetwindow.PyGetWindowException('Error code from Windows: %s - %s' % (errorCode, _formatMessage(errorCode)))
98
99
PyGetWindowException: Error code from Windows: 0 - The operation completed successfully.
I'm seeing the same thing in Windows simply trying to connect to a Notepad window. I'm using click on the window to achieve an activation instead
fw = pyautogui.getWindowsWithTitle('Notepad')
fw = fw[0]
fw.maximize()
pyautogui.click(fw.center); pyautogui.write('abc', 0.01)
Hello guys,
I have encountered the same issue and I'm sorry if my anwser/workaround looks novice but thats what I am so yeah.
Searching for the reason why this happens I fell down the rabbit whole but I think I some what have an anwser but unfortunately I did not find the sollution.
Any how what appears to be happening that it does not find a procces/window to foccus on when the funtion is called. Just the program. Once you use the following as an example:
import pywinauto
import pygetwindow as gw
def focus_to_window(window_title=None):
window = gw.getWindowsWithTitle(window_title)[0]
if window.isActive == False:
pywinauto.application.Application().connect(handle=window._hWnd).top_window().set_focus()
It now seems to bee connected to the procces. after a function like this it seems that the .activate() function seems to work perfectly fine since its pointed to that procces. Until it is minimized because there in no window to focus on.
I have tested it with multiple windows of notepad and looks like it keeps connected to one specific window since "its pointed" to there to bring it to the foreground.
Hopefully I can find the precise reason and get a fully working sollution instead of a workaround
cheers
I use the following workaround:
<import` pygetwindow, mouse
def activate(win):
win.restore()
mouse.move(*win.center)
mouse.click(button='left')>
type(win)
<class 'pygetwindow._pygetwindow_win.Win32Window'>
``
Please try run Application with administrator privileges in Windows10.
This may solve activate error.
I'm not pretty sure why this happens, but I also have a workaround that may look cleaner:
import pygetwindow as gw
hwnd = gw.getWindowsWithTitle('Notepad')
if hwnd != []:
try:
hwnd[0].activate()
except:
hwnd[0].minimize()
hwnd[0].maximize()
What we do here is try to activate the desired window, then, if this fails, minimize and maximize the same window. No need to import extra libraries or complicated procedures.
I'm not pretty sure why this happens, but I also have a workaround that may look cleaner:
import pygetwindow as gw hwnd = gw.getWindowsWithTitle('Notepad') if hwnd != []: try: hwnd[0].activate() except: hwnd[0].minimize() hwnd[0].maximize()
What we do here is try to activate the desired window, then, if this fails, minimize and maximize the same window. No need to import extra libraries or complicated procedures.
This works great! the only thing I'd add is that I also used hwnd[0].restore() at the end, because my program isn't maximized. So now it works great!
What worked for me was:
import pyautogui as pag
WINDOW_NAME = "WINDOW NAME OF YOUR APP"
app_window = pag.getWindowsWithTitle(WINDOW_NAME)
if len(app_window) > 0:
print("Application is running...")
else:
print("Application is not running...")
return False
if app_window[0].isActive == False:
pag.click(app_window[0].activate())
print("Brought window application to the foreground.")
else:
print("Application already in foreground.")
return True
The trick was the pag.click(app_window[0].activate())
part.
hwnd = gw.getWindowsWithTitle('Notepad')
if hwnd != []:
try:
hwnd[0].activate()
except:
hwnd[0].minimize()
hwnd[0].maximize()
This actually works, Thanks Man
I'm not pretty sure why this happens, but I also have a workaround that may look cleaner:
import pygetwindow as gw hwnd = gw.getWindowsWithTitle('Notepad') if hwnd != []: try: hwnd[0].activate() except: hwnd[0].minimize() hwnd[0].maximize()
What we do here is try to activate the desired window, then, if this fails, minimize and maximize the same window. No need to import extra libraries or complicated procedures.
It worked. thanks
The trick was the
pag.click(app_window[0].activate())
part.
This didn't work for me as written but it got me over the hump and yours lead to what I think is the most elegant solution. You don't need to minimize, maximize, check if activated. You just need to click() and activate().
import pygetwindow as gw
import pyautogui as ag
for window in gw.getWindowsWithTitle(''):
... loop and regex to the window you want ...
ag.click()
window.activate()
Many thanks
window.minimize()
window.restore()
window.minimize() is used to minimize the specified window, hiding it in the taskbar or system tray.
window.restore() is used to restore a minimized window to its normal state, bringing it back from the taskbar or system tray and displaying it again on the screen.
LLego años tarde y en español pero esto funciono para mi
Agreguen el envio de ese cartacter antes de cambiar el foco.
Todos los creditos a los sabios de aqui https://stackoverflow.com/questions/14295337/win32gui-setactivewindow-error-the-specified-procedure-could-not-be-found
import win32gui, win32com.client
shell = win32com.client.Dispatch("WScript.Shell")
shell.SendKeys('%')
win32gui.SetForegroundWindow(window)