this works perfectly if window is not minimized, but when window is minimized i am not be able to set the focus on it.
from pywinauto.application import Application
app = Application(backend="uia")
try:
app = app.connect(title_re=".*Bloc*.", visible_only=False)
except:
print("Not visible...")
exit()
app_top_window = app.top_window()
app_top_window.maximize()
How to workaround this and bring the minimized window to the foreground again?
If connect calls works fine, it should work like this:
top_window = app.window(title_re=".*Bloc*.", visible_only=False)
top_window.restore().set_focus() # sometimes .restore() is redundant
app.top_window() is not recommended to use as it sticks to the top window at the moment of .top_window() call. Top window may change at any moment. Also it's for visible top window only.
Related
I developed a script for pcba testing and it works fine.
Now I want to implement a very simple flow like this:
Window popup just to let the user start the test
Run the test without any window (the terminal is just fine)
Window popup to show pass/fail result of the test
I already developed the two windows in two other .py files, which run without any problems when "standalone".
If I implement these two within the script, the first appears normally, but the second opens and closes istantly.
Without being too complicated, the test function is defined in serial.py, the first window in infoBox.py and the final window in getResult.py.
Inside the serial.py I tried:
import infoBox
import getResult
[...]
def work():
[...]
if __name__ == '__main__':
app1 = QApplication([])
win1 = infoBox.infoBox("""Turn on 24V alim and press OK.""")
win1.show()
app.exec()
[...]
work()
[...]
app2 = QApplication([])
generateWindow(esiti=lst_esiti, info=lst_info) # <------- this calls getResult.getResult class and .show() the widget
win2 = getResult.getResult(lst_esito=lst_esiti, lst_info=lst_info)
win2.show()
app.exec()
So, when serial.py is lounched by terminal, the infoBox instance appears, the work() function does what it has to, and the getResult instance (which has a OK button to be closed) is instantly closed.
Maybe the error is the definition of two QApplication? I tried a lot but I'm not able to manage it.
Thank you very much.
Finally I came up with this.
It was easier than expected...
Solved opening a unique QApplication and call app.exec() after each subclass calling.
I am trying to automate some GUI stuff in Windows. I open a settings window but when waiting for it to open before continuing, it times out:
from pywinauto import Application
app = Application()
app.start(r"explorer shell:::{05d7b0f4-2121-4eff-bf6b-ed3f69b894d9}")
app.window(title_re=".*Notification Area Icons*").wait("exists", timeout=20)
app = Application(backend="uia").connect(title_re=".*Notification Area Icons*")
main_dlg = app.window(title_re=".*Notification Area Icons*")
main_dlg.print_control_identifiers()
Even with the timeout at 20 seconds, it times out. However, if I replace app.window(title_re=".*Notification Area Icons*").wait("exists", timeout=20) with sleep(5) (and add the appropriate import) it works fine. I know the window title is correct because it will print out the control ids when using sleep. I've tried using "exists" and "visible" for the wait as well. I think the other options are more strict so I'm not sure why the wait is not working.
It's possible there are few explorer.exe processes. You can try process-agnostic way:
from pywinauto import Desktop
window_wrapper = Desktop(backend="uia").window(title_re=".*Notification Area Icons*").wait("exists", timeout=20)
print(window_wrapper.process_id())
# and compare with print(app.process)
I have a very simple python code: a tkitner button that process some images in the background. I wanted to open a tkinter toplevel to show the user that it was doing something, but for my surprise is not working as I thought it would. The command on the tk.Button is the next method:
def processing(self):
"""Starts the images processing"""
# Open a Tk.Toplevel
aux_topLevel = Splash(self.window) # a simple Tk.Toplevel class, that works perfectly
self._process_images() # starts processing the images
# I wanted to kill here the topLevel created before
aux_topLevel.destroy()
My surprise: the window is displayed once the processing images is done (tried it out adding prints and time.sleep), however, i couldn't display the TopLevel when I wanted to.
Is there anything am I doing wrong? Any help is appreciated. Thank you.
Consider the following example and try to run it.
What you'd think should happen is that the new Toplevel window should open, some event happens for a period of time and then the window is destroyed.
What actually happens is the window is opened, but never displayed, the task occurs and then the window is destroyed.
from tkinter import *
import time
def processing():
new = Toplevel(root)
new.geometry("200x150")
lbl = Label(new,text="--")
lbl.grid()
for i in range(50):
time.sleep(0.1)
#Un-comment the line below to fix
#root.update()
print(i)
lbl['text'] = "{}".format(i)
new.destroy()
root = Tk()
root.geometry('200x100')
btnGo = Button(root,text="Go",command=processing)
btnGo.grid()
root.mainloop()
If you un-comment out the root.update() line and re-run the code, the window will be displayed.
There are better ways to deal with tasks that takes a while to process, such as threading.
Besides looking for answers on this site, I checked out
pywinauto.application module
and
Getting Started Guide
but I'm still stumped.
I manually start notepad and want the first while block of the following code to make the notepad window visible. The second while block works but I am confused about the line
dlg_spec = app.UntitledNotepad
What is going on here? What kind of a python method is this?
Question: How do I get the first while block of code make the window titled
Untitled - Notepad
visible?
#--------*---------*---------*---------*---------*---------*---------*---------*
# Desc: Set focus on a window
# #--------*---------*---------*---------*---------*---------*---------*---------*
import sys
import pywinauto
# # Manually started Notepad
# # Want to make it visible (windows focus)
# # Program runs, but...
while 1:
handle = pywinauto.findwindows.find_windows(title='Untitled - Notepad')[0]
app = pywinauto.application.Application()
ac = app.connect(handle=handle)
print(ac)
topWin = ac.top_window_()
print(topWin)
sys.exit()
# # Working Sample Code
while 0:
app = pywinauto.Application().start('notepad.exe')
# describe the window inside Notepad.exe process
# # ?1: '.UntitledNotepad' - huh?
dlg_spec = app.UntitledNotepad
# wait till the window is really open
actionable_dlg = dlg_spec.wait('visible')
sys.exit()
For convenience this code does the trick:
# # Manually started Notepad
# # Want to make it visible (windows focus).
# #
# # Two or three lines solution provided by
# # Vasily Ryabov's overflow answer
# # (wrapper ribbon and bow stuff).
while 1:
app = pywinauto.application.Application().connect(title="Untitled - Notepad")
dlg_spec = app.window(best_match="UntitledNotepad")
dlg_spec.set_focus()
sys.exit()
I would suggest you using the win32gui library for this task as shown below:
import win32gui
hwnd = win32gui.FindWindow(None, 'Notepad')
win32gui.SetForegroundWindow(hwnd)
win32gui.ShowWindow(hwnd, 9)
The number 9 represents SW_RESTORE as shown here
Well, the first while loop should be re-written using the same methods except find_windows (it's low level and not recommended for direct usage). You need method .set_focus() to bring the window to foreground.
app = pywinauto.Application().connect(title="Untitled - Notepad")
app.UntitledNotepad.set_focus()
Creating window specification dlg_spec = app.UntitledNotepad means that app method __getattribute__ is called. Finally this line is equivalent to dlg_spec = app.window(best_match="UntitledNotepad"). To find the actual wrapper you need to call .wait(...) or .wrapper_object().
But when you call an action (like .set_focus()), Python can do the wrapper_object() call for you implicitly (while accessing attribute set_focus dynamically).
To display a wxPython window in full screen mode you use:
ShowFullScreen(True)
How do you get out of full screen though? I've tried the obvious way:
ShowFullScreen(True)
sleep(5)
ShowFullScreen(False)
This doesn't work though. When I run the script, nothing appears. After 5 seconds a window roughly 200x250 appears in the top-left corner of the screen, without anything inside of it. It doesn't appear to have any borders either.
If I change this to
showFullScreen(True)
then I get stuck with a full screen window that I have to use Alt + F2 -> xkill to get out of.
It looks like you need to Show() the window first. (According to the documentation, you shouldn't have to. Maybe this is a bug.) I tested on Mac OS X and Windows - they both exhibit issues if you don't call Show() first.
Also note that you shouldn't sleep in the main GUI thread. You'll hang the UI. Using CallLater is one potential solution, as shown in my example.
Working example:
import wx
def main():
app = wx.PySimpleApp()
frame = wx.Frame(None, -1, 'Full Screen Test')
frame.Show()
frame.ShowFullScreen(True)
wx.CallLater(5000, frame.ShowFullScreen, False)
app.MainLoop()
if __name__ == '__main__':
main()
The documentation for ShowFullScreen reads:
ShowFullScreen(show, style=wx.FULLSCREEN_ALL)
Depending on the value of show parameter the window is either shown full screen or restored to its normal state.
Parameters:
show (bool)
style (long): is a bit list containing some or all of the following values, which indicate what elements of the window to hide in full-screen mode:
wx.FULLSCREEN_NOMENUBAR
wx.FULLSCREEN_NOTOOLBAR
wx.FULLSCREEN_NOSTATUSBAR
wx.FULLSCREEN_NOBORDER
wx.FULLSCREEN_NOCAPTION
wx.FULLSCREEN_ALL (all of the above)
So put your Full Screen toggle event/s in a Menu and start full screen mode with:
self.window.ShowFullScreen(True, style=(wx.FULLSCREEN_NOTOOLBAR | wx.FULLSCREEN_NOSTATUSBAR |wx.FULLSCREEN_NOBORDER |wx.FULLSCREEN_NOCAPTION))
Note that I omitted wx.FULLSCREEN_NOMENUBAR, in this way you will still be able to access the menu to turn full screen mode off again.