键盘焦点在 Pywinauto 中不起作用

Keyboard Focus Not working in Pywinauto

屏幕截图的左侧部分显示了我正在尝试自动化的 windows,屏幕截图的右侧部分是 Microsoft 的 Inspect 工具。

我在 Python 3.5.2 上使用 Pywinauto 0.6.1,在我的 Win 10-x64 机器上使用 Anaconda Distribution。这是我的代码:

from pywinauto.application import Application, WindowSpecification
from pywinauto.controls.uiawrapper import UIAWrapper
#
app = Application(backend="uia").connect(title = 'Scanner: PravinsSignalAPP')
dlg_spec = app.window(title='Scanner: PravinsSignalAPP')
dlg1 = WindowSpecification.child_window(dlg_spec, title="ctlScanner")
dlg2 = WindowSpecification.child_window(dlg1, title="DataGridView")
dlg3 = WindowSpecification.child_window(dlg2, title="Row 0")
dlg4 = WindowSpecification.child_window(dlg3, title="Trade Time Row 0", control_type="DataItem")
#
#UIAWrapper.set_focus(dlg_spec)
UIAWrapper.set_focus(dlg4)

当我尝试执行此操作时,出现以下错误:

"ElementNotFoundError: {'top_level_only': False, 'title': 'ctlScanner', 'backend': 'uia', 'parent': <pywinauto.uia_element_info.UIAElementInfo object at 0x000001AE6CE31E48>}" 

我可以将焦点放在 dlg_spec 上。我的疑问是 - 如何将 Focus 设置为 dlg4 ?

这是 print (dlg_spec.print_control_identifiers()) 的输出:

Control Identifiers:

Dialog - 'Scanner: PravinsSignalAPP'    (L-8, T-8, R1928, B1058)
['Dialog', 'Scanner: PravinsSignalAPP', 'Scanner: PravinsSignalAPPDialog']
child_window(title="Scanner: PravinsSignalAPP", auto_id="frmPopoutChart", control_type="Window")
   | 
   | Pane - ''    (L0, T23, R1920, B1050)
   | ['', 'Pane0', 'Pane', 'Pane1', '1', '0']
   | child_window(auto_id="ctlScanner", control_type="Pane")
   |    | 
   |    | Table - 'DataGridView'    (L0, T198, R1920, B1049)
   |    | ['DataGridView', 'DataGridViewTable', 'Table']
   |    | child_window(title="DataGridView", auto_id="grdResults", control_type="Table")
   |    |    | 
   |    |    | Custom - 'Top Row'    (L0, T198, R1919, B219)
   |    |    | ['Custom1', 'Top RowCustom', 'Custom0', 'Top Row', 'Custom']
   |    |    | child_window(title="Top Row", control_type="Custom")
   |    |    |    | 
   |    |    |    | Header - 'Trade Time'    (L1, T198, R101, B219)
   |    |    |    | ['Header', 'Header1', 'Header0', 'Trade TimeHeader', 'Trade Time']
   |    |    |    | child_window(title="Trade Time", control_type="Header")
   |    |    |    | 
   |    |    |    | Header - 'Symbol'    (L101, T198, R201, B219)
   |    |    |    | ['SymbolHeader', 'Symbol', 'Header2']
   |    |    |    | child_window(title="Symbol", control_type="Header")
   |    |    |    | 
   |    |    |    | Header - 'Last'    (L201, T198, R301, B219)
   |    |    |    | ['Header3', 'Last', 'LastHeader']
   |    |    |    | child_window(title="Last", control_type="Header")
   |    |    |    | 
   |    |    |    | Header - 'Volume'    (L301, T198, R401, B219)
   |    |    |    | ['Volume', 'VolumeHeader', 'Header4']
   |    |    |    | child_window(title="Volume", control_type="Header")
   |    |    |    | 
   |    |    |    | Header - 'Alert Time'    (L401, T198, R501, B219)
   |    |    |    | ['Alert TimeHeader', 'Alert Time', 'Header5']
   |    |    |    | child_window(title="Alert Time", control_type="Header")
   |    |    |    | 
   |    |    |    | Header - 'Trade'    (L501, T198, R601, B219)
   |    |    |    | ['Trade', 'Header6', 'TradeHeader']
   |    |    |    | child_window(title="Trade", control_type="Header")
   |    |    |    | 
   |    |    |    | Header - 'Chart'    (L601, T198, R701, B219)
   |    |    |    | ['Chart', 'Header7', 'ChartHeader']
   |    |    |    | child_window(title="Chart", control_type="Header")
   |    |    |    | 
   |    |    |    | Header - 'Settings'    (L701, T198, R801, B219)
   |    |    |    | ['SettingsHeader', 'Settings', 'Header8']
   |    |    |    | child_window(title="Settings", control_type="Header")
   |    |    | 
   |    |    | Custom - 'Row 0'    (L1, T219, R1919, B244)
   |    |    | ['Custom2', 'Row 0Custom', 'Row 0']
   |    |    | child_window(title="Row 0", control_type="Custom")
   |    |    |    | 
   |    |    |    | DataItem - 'Trade Time Row 0'    (L1, T219, R101, B244)
   |    |    |    | ['Trade Time Row 0', 'DataItem', 'DataItem0', 'DataItem1', 'Trade Time Row 0DataItem']
   |    |    |    | child_window(title="Trade Time Row 0", control_type="DataItem")
   |    |    |    | 
   |    |    |    | DataItem - 'Symbol Row 0'    (L101, T219, R201, B244)
   |    |    |    | ['Symbol Row 0', 'Symbol Row 0DataItem', 'DataItem2']
   |    |    |    | child_window(title="Symbol Row 0", control_type="DataItem")
   |    |    |    | 
   |    |    |    | DataItem - 'Last Row 0'    (L201, T219, R301, B244)
   |    |    |    | ['DataItem3', 'Last Row 0DataItem', 'Last Row 0']
   |    |    |    | child_window(title="Last Row 0", control_type="DataItem")
   |    |    |    | 
   |    |    |    | DataItem - 'Volume Row 0'    (L301, T219, R401, B244)
   |    |    |    | ['Volume Row 0DataItem', 'DataItem4', 'Volume Row 0']
   |    |    |    | child_window(title="Volume Row 0", control_type="DataItem")
   |    |    |    | 
   |    |    |    | DataItem - 'Alert Time Row 0'    (L401, T219, R501, B244)
   |    |    |    | ['Alert Time Row 0DataItem', 'DataItem5', 'Alert Time Row 0']
   |    |    |    | child_window(title="Alert Time Row 0", control_type="DataItem")
   |    |    |    | 
   |    |    |    | DataItem - 'Trade Row 0'    (L501, T219, R601, B244)
   |    |    |    | ['Trade Row 0DataItem', 'Trade Row 0', 'DataItem6']
   |    |    |    | child_window(title="Trade Row 0", control_type="DataItem")
   |    |    |    | 
   |    |    |    | DataItem - 'Chart Row 0'    (L601, T219, R701, B244)
   |    |    |    | ['Chart Row 0DataItem', 'DataItem7', 'Chart Row 0']
   |    |    |    | child_window(title="Chart Row 0", control_type="DataItem")
   |    |    |    | 
   |    |    |    | DataItem - 'Settings Row 0'    (L701, T219, R801, B244)
   |    |    |    | ['Settings Row 0DataItem', 'Settings Row 0', 'DataItem8']
   |    |    |    | child_window(title="Settings Row 0", control_type="DataItem")
   |    |    | 
   |    |    | Custom - 'Row 1'    (L1, T244, R1919, B269)
   |    |    | ['Row 1', 'Row 1Custom', 'Custom3']
   |    |    | child_window(title="Row 1", control_type="Custom")
   |    |    |    | 
   |    |    |    | DataItem - 'Trade Time Row 1'    (L1, T244, R101, B269)
   |    |    |    | ['Trade Time Row 1', 'DataItem9', 'Trade Time Row 1DataItem']
   |    |    |    | child_window(title="Trade Time Row 1", control_type="DataItem")
   |    |    |    | 
   |    |    |    | DataItem - 'Symbol Row 1'    (L101, T244, R201, B269)
   |    |    |    | ['Symbol Row 1', 'DataItem10', 'Symbol Row 1DataItem']
   |    |    |    | child_window(title="Symbol Row 1", control_type="DataItem")
   |    |    |    | 
   |    |    |    | DataItem - 'Last Row 1'    (L201, T244, R301, B269)
   |    |    |    | ['Last Row 1', 'DataItem11', 'Last Row 1DataItem']
   |    |    |    | child_window(title="Last Row 1", control_type="DataItem")
   |    |    |    | 
   |    |    |    | DataItem - 'Volume Row 1'    (L301, T244, R401, B269)
   |    |    |    | ['Volume Row 1DataItem', 'Volume Row 1', 'DataItem12']
   |    |    |    | child_window(title="Volume Row 1", control_type="DataItem")
   |    |    |    | 
   |    |    |    | DataItem - 'Alert Time Row 1'    (L401, T244, R501, B269)
   |    |    |    | ['DataItem13', 'Alert Time Row 1', 'Alert Time Row 1DataItem']
   |    |    |    | child_window(title="Alert Time Row 1", control_type="DataItem")
   |    |    |    | 
   |    |    |    | DataItem - 'Trade Row 1'    (L501, T244, R601, B269)
   |    |    |    | ['DataItem14', 'Trade Row 1DataItem', 'Trade Row 1']
   |    |    |    | child_window(title="Trade Row 1", control_type="DataItem")
   |    |    |    | 
   |    |    |    | DataItem - 'Chart Row 1'    (L601, T244, R701, B269)
   |    |    |    | ['DataItem15', 'Chart Row 1DataItem', 'Chart Row 1']
   |    |    |    | child_window(title="Chart Row 1", control_type="DataItem")
   |    |    |    | 
   |    |    |    | DataItem - 'Settings Row 1'    (L701, T244, R801, B269)
   |    |    |    | ['Settings Row 1DataItem', 'DataItem16', 'Settings Row 1']
   |    |    |    | child_window(title="Settings Row 1", control_type="DataItem")
   |    |    | 
   |    |    | Custom - 'Row 2'    (L1, T269, R1919, B294)
   |    |    | ['Row 2', 'Row 2Custom', 'Custom4']
   |    |    | child_window(title="Row 2", control_type="Custom")
   |    |    |    | 
   |    |    |    | DataItem - 'Trade Time Row 2'    (L1, T269, R101, B294)
   |    |    |    | ['DataItem17', 'Trade Time Row 2', 'Trade Time Row 2DataItem']
   |    |    |    | child_window(title="Trade Time Row 2", control_type="DataItem")
   |    |    |    | 
   |    |    |    | DataItem - 'Symbol Row 2'    (L101, T269, R201, B294)
   |    |    |    | ['Symbol Row 2', 'DataItem18', 'Symbol Row 2DataItem']
   |    |    |    | child_window(title="Symbol Row 2", control_type="DataItem")
   |    |    |    | 
   |    |    |    | DataItem - 'Last Row 2'    (L201, T269, R301, B294)
   |    |    |    | ['Last Row 2', 'DataItem19', 'Last Row 2DataItem']
   |    |    |    | child_window(title="Last Row 2", control_type="DataItem")
   |    |    |    | 
   |    |    |    | DataItem - 'Volume Row 2'    (L301, T269, R401, B294)
   |    |    |    | ['Volume Row 2DataItem', 'DataItem20', 'Volume Row 2']
   |    |    |    | child_window(title="Volume Row 2", control_type="DataItem")
   |    |    |    | 
   |    |    |    | DataItem - 'Alert Time Row 2'    (L401, T269, R501, B294)
   |    |    |    | ['Alert Time Row 2DataItem', 'DataItem21', 'Alert Time Row 2']
   |    |    |    | child_window(title="Alert Time Row 2", control_type="DataItem")
   |    |    |    | 
   |    |    |    | DataItem - 'Trade Row 2'    (L501, T269, R601, B294)
   |    |    |    | ['DataItem22', 'Trade Row 2DataItem', 'Trade Row 2']
   |    |    |    | child_window(title="Trade Row 2", control_type="DataItem")
   |    |    |    | 
   |    |    |    | DataItem - 'Chart Row 2'    (L601, T269, R701, B294)
   |    |    |    | ['Chart Row 2DataItem', 'Chart Row 2', 'DataItem23']
   |    |    |    | child_window(title="Chart Row 2", control_type="DataItem")
   |    |    |    | 
   |    |    |    | DataItem - 'Settings Row 2'    (L701, T269, R801, B294)
   |    |    |    | ['DataItem24', 'Settings Row 2', 'Settings Row 2DataItem']
   |    |    |    | child_window(title="Settings Row 2", control_type="DataItem")
   |    | 
   |    | Pane - 'Scanner Settings'    (L3, T29, R361, B166)
   |    | ['Pane2', 'Scanner SettingsPane', 'Scanner Settings']
   |    | child_window(title="Scanner Settings", auto_id="grpSaveLoadScanner", control_type="Pane")
   |    |    | 
   |    |    | Button - 'Edit Script'    (L23, T117, R107, B142)
   |    |    | ['Button', 'Edit ScriptButton', 'Button1', 'Button0', 'Edit Script']
   |    |    | child_window(title="Edit Script", auto_id="nEditButton", control_type="Button")
   |    |    | 
   |    |    | Button - 'Stop'    (L138, T117, R222, B142)
   |    |    | ['Button2', 'Stop', 'StopButton']
   |    |    | child_window(title="Stop", auto_id="nLoadButton", control_type="Button")
   |    |    | 
   |    |    | Button - 'Delete'    (L258, T117, R342, B142)
   |    |    | ['Button3', 'Delete', 'DeleteButton']
   |    |    | child_window(title="Delete", auto_id="cmdDelete", control_type="Button")
   |    |    | 
   |    |    | Pane - 'nuiPanel1'    (L4, T51, R360, B165)
   |    |    | ['nuiPanel1Pane', 'Pane3', 'nuiPanel1']
   |    |    | child_window(title="nuiPanel1", auto_id="nuiPanel1", control_type="Pane")
   |    |    |    | 
   |    |    |    | Pane - 'PravinsSignalAPP'    (L129, T66, R295, B91)
   |    |    |    | ['PravinsSignalAPPPane', 'PravinsSignalAPP', 'Pane4']
   |    |    |    | child_window(title="PravinsSignalAPP", auto_id="cboScanners", control_type="Pane")
   |    |    |    | 
   |    |    |    | Pane - 'Scanner Name'    (L26, T72, R100, B85)
   |    |    |    | ['Scanner NamePane', 'Scanner Name', 'Pane5']
   |    |    |    | child_window(title="Scanner Name", auto_id="scannerNameLabel", control_type="Pane")
   |    | 
   |    | Button - 'New Scanner'    (L390, T85, R487, B110)
   |    | ['Button4', 'New Scanner', 'New ScannerButton']
   |    | child_window(title="New Scanner", auto_id="cmdScanner", control_type="Button")
   | 
   | TitleBar - 'None'    (L16, T-5, R1920, B23)
   | ['2', 'TitleBar']

   |    | 
   |    | Menu - 'System'    (L0, T0, R22, B22)
   |    | ['System', 'System1', 'Menu', 'System0', 'SystemMenu']
   |    | child_window(title="System", auto_id="MenuBar", control_type="MenuBar")
   |    |    | 
   |    |    | MenuItem - 'System'    (L0, T0, R22, B22)
   |    |    | ['SystemMenuItem', 'MenuItem', 'System2']
   |    |    | child_window(title="System", control_type="MenuItem")
   |    | 
   |    | Button - 'Minimize'    (L1779, T0, R1826, B22)
   |    | ['MinimizeButton', 'Button5', 'Minimize']
   |    | child_window(title="Minimize", control_type="Button")
   |    | 
   |    | Button - 'Restore'    (L1826, T0, R1872, B22)
   |    | ['Button6', 'Restore', 'RestoreButton']
   |    | child_window(title="Restore", control_type="Button")
   |    | 
   |    | Button - 'Close'    (L1872, T0, R1919, B22)
   |    | ['Close', 'CloseButton', 'Button7']
   |    | child_window(title="Close", control_type="Button")
None

首先您需要确保找到每个父元素。当您创建 WindowSpecification 时,它实际上并没有找到任何元素。您必须调用特定方法来强制搜索元素或显式调用 .wrapper_object() 方法,这在生产中可以省略。例如:

from pywinauto.application import Application

app = Application(backend="uia").connect(title = 'Scanner: PravinsSignalAPP')
dlg_spec = app.window(title='Scanner: PravinsSignalAPP')
print('dlg_spec wrapper:', dlg_spec.wrapper_object())

dlg1 = dlg_spec.child_window(auto_id="ctlScanner")
print('dlg1 wrapper:', dlg1.wrapper_object())

dlg2 = dlg1.child_window(title="DataGridView")
print('dlg2 wrapper:', dlg2.wrapper_object())

dlg3 = dlg2.child_window(title="Row 0")
print('dlg3 wrapper:', dlg3.wrapper_object())

dlg4 = dlg3.child_window(title="Trade Time Row 0", control_type="DataItem")
print('dlg4 wrapper:', dlg4.wrapper_object())

#dlg_spec.set_focus()
dlg4.set_focus()

属性 HasKeyboardFocusIsKeyboardFocusable 也与 pywinauto 的方法 .set_keyboard_focus() 相关。 .set_focus() 只是使 window 处于活动状态。


更新:错误在 属性 名称中,应该是 auto_id="ctlScanner".