pywinauto: how to SendKeys on a ListView which doesn't accept SendKeys?

6.7k Views Asked by At

I did select an item from a list (using the code bellow), I'm need now to send a ctrl+E. The problem is that somehow the SendKeys method isn't available, I can't use SendKeys('^e'). (This shortcut will edit the selected item in the ditto app)

from pywinauto.application import Application
from pywinauto import findbestmatch
from pywinauto import keyboard  #not sure if I need to import it


ditto=Application().connect(path='Ditto.exe')

#---- print all available methods of the object
print(dir(ditto.ditto.SysListView321.wrapper_object())) #( the list does not contains 'SendKeys')


#-----Find and select the item (containing 'xxx') in the SysListView321
#The list of texts to search through 
texts = ditto.ditto.SysListView321.texts()[1:] #skip window text itself, use only item texts

# The list of items corresponding (1 to 1) to the list of texts to search through.
items = ditto.ditto.SysListView321.items()   #>>[]    
found_item = findbestmatch.find_best_match('xxx', texts, items, limit_ratio=0.1).Select()

Some Errors:

ditto.ditto.SysListView321.SendKeys('^e')

... WindowSpecification class has no 'SendKeys' method

ditto.ditto.SysListView321.keyboard.SendKeys('^e')

... findbestmatch.MatchError: Could not find 'keyboard' in 'dict_keys(['', 'Header'])'

[EDIT] (More errors)

ditto.ditto.SysListView321.type_keys('^e')

win32gui.SetForegroundWindow(self.handle) pywintypes.error: (0, 'SetForegroundWindow', 'No error message is available')

 keyboard.send_keys('^e')

AttributeError: module 'pywinauto.keyboard' has no attribute 'send_keys'


(Ps. for beginners: app.Ditto is equivalent to app.window(best_match='Ditto') )

2

There are 2 best solutions below

14
Vasily Ryabov On BEST ANSWER

For the specified UI element this method is

# it will activate target window if it's not in focus
ditto.ditto.SysListView321.type_keys('^e')

but

keyboard.SendKeys('^e') # should work also if you don't change active window

It can be used without binding to any specific control.

So you shouldn't try using module name (like keyboard) as an attribute name of any object. It's Python. Just learn Python basics and you will understand pywinauto better as well.

0
J. Does On

To complete Vasily's answer. Here is the code needed to edit a single ditto item (it works... most of the time)

from pywinauto import findbestmatch
from pywinauto.application import Application
from pywinauto import remote_memory_block
from pywinauto import keyboard
from pywinauto import timings
import time  #needed for time.sleep(3)


keyboard.SendKeys('^*') # custom shortcut to launch the specific ditto "group" 
time.sleep(2)  # wait 2 sec for the app

ditto=Application().connect(path='Ditto.exe')
time.sleep(0.5) 

##find & select item

#The list of texts to search through: 
texts = ditto.ditto.SysListView321.texts()[1:] #skip window text itself

# The list of items corresponding (1 to 1) to the list of texts to search through.
items = ditto.ditto.SysListView321.items()   #>>[]  

found_item = findbestmatch.find_best_match('test', texts, items, limit_ratio=0.1).Select()

## Extra: open the item in editor
# Bring the window to the foreground first
ditto.ditto.set_keyboard_focus() # (work also with set_focus but it remove the cursor) 

# edit the selected entry (it's a shortcut)
keyboard.SendKeys('^e') 

# Wait (for the windows to load)
time.sleep(1) # 1 sec

# Select all
keyboard.SendKeys('^a')

ditto.Editor.close()