Я пытаюсь автоматизировать некоторые задачи обслуживания в программном обеспечении ERP. Есть «программы», которые открываются из боковой панели и будут открываться как еще одна вкладка. Проблема в том, что возможно создать несколько экземпляров (вкладок) одной и той же программы. Я хочу убедиться, что когда я запускаю программу, я выбираю правильную вкладку (чтобы убедиться, что на ней нет данных и я не перезаписываю что-то еще). Кажется, я не могу найти способ связать вкладки с диалоговыми окнами, так как они, кажется, находятся на одном уровне в иерархии.
вывод print_control_identifiers:
child_window(title="QAD Enterprise Applications", auto_id="ShellForm", control_type="Window")
|
| TabControl - '' (L352, T48, R1920, B80)
| ['TabControl', 'TabControlUser Maintenance', '', '0', '1']
| child_window(auto_id="920582", control_type="Tab")
| |
| | TabItem - 'User Maintenance' (L354, T53, R479, B79)
| | ['User Maintenance', 'TabItem', 'User MaintenanceTabItem', 'User Maintenance0', 'User Maintenance1', 'TabItem0', 'TabItem1', 'User MaintenanceTabItem0', 'User MaintenanceTabItem1']
| | child_window(title="User Maintenance", control_type="TabItem")
| |
| | TabItem - 'User Maintenance' (L478, T53, R603, B79)
| | ['User Maintenance2', 'TabItem2', 'User MaintenanceTabItem2']
| | child_window(title="User Maintenance", control_type="TabItem")
| |
| | TabItem - 'User Maintenance' (L602, T53, R727, B79)
| | ['User Maintenance3', 'TabItem3', 'User MaintenanceTabItem3']
| | child_window(title="User Maintenance", control_type="TabItem")
| |
| | TabItem - 'User Maintenance' (L726, T53, R851, B80)
| | ['User Maintenance4', 'TabItem4', 'User MaintenanceTabItem4']
| | child_window(title="User Maintenance", control_type="TabItem")
|
| Pane - '' (L347, T48, R352, B1027)
| ['2', 'Pane', 'Pane0', 'Pane1']
| child_window(auto_id="_splitter", control_type="Pane")
|
| Pane - '' (L0, T48, R347, B1027)
| ['3', 'Pane2']
| child_window(auto_id="pnlSideBarMenu", control_type="Pane")
| |
| | Pane - '' (L0, T48, R347, B1027)
| | ['4', 'Pane3']
| | child_window(auto_id="pnlSideBar", control_type="Pane")
|
| Pane - '' (L0, T23, R1920, B48)
| ['36', 'Pane29']
| child_window(auto_id="pnlTopHeaderParent", control_type="Pane")
| |
| | Pane - '' (L0, T23, R1920, B48)
| | ['37', 'Pane30']
| | child_window(auto_id="pnlTopHeader", control_type="Pane")
|
| Pane - '' (L352, T48, R1920, B1027)
| ['41', 'Pane32']
| child_window(auto_id="1182740", control_type="Pane")
| |
| | Dialog - 'User Maintenance' (L352, T80, R1920, B1027)
| | ['Dialog2', 'User Maintenance6', 'User MaintenanceDialog', 'User MaintenanceDialog0', 'User MaintenanceDialog1']
| | child_window(title="User Maintenance", auto_id="QViewForm", control_type="Window")
| |
| | Dialog - 'User Maintenance' (L352, T80, R1920, B1027)
| | ['Dialog3', 'User Maintenance7', 'User MaintenanceDialog2']
| | child_window(title="User Maintenance", auto_id="QViewForm", control_type="Window")
| |
| | Dialog - 'User Maintenance' (L352, T80, R1920, B1027)
| | ['Dialog4', 'User Maintenance8', 'User MaintenanceDialog3']
| | child_window(title="User Maintenance", auto_id="QViewForm", control_type="Window")
| |
| | Dialog - 'User Maintenance' (L352, T80, R1920, B1027)
| | ['Dialog5', 'User Maintenance9', 'User MaintenanceDialog4']
| | child_window(title="User Maintenance", auto_id="QViewForm", control_type="Window")
|
Таким образом, я могу контролировать и выбирать вкладки с помощью элемента TabControl «User Maintenance», и я могу изменять содержимое в диалоге «User Maintenance», но я не могу найти ничего, что связывает их вместе.
Я пробовал некоторые вещи, такие как циклическое переключение вкладок и возвращение индекса активной вкладки:
tabctrl = wnd.child_window(control_type='Tab')
idx = 0
for t in tabctrl.iter_children():
if (t.window_text() == 'User Maintenance'):
t.select()
break
else:
idx += 1
tab_handle = pane.children()[idx].handle
pane = wnd.child_window(class_name='WindowsForms10.MDICLIENT.app.0.2004eee', control_type='Pane')
tab = pane.child_window(handle=tab_handle, control_type="Window", title='User Maintenance')
Но индексы tabctrl.children () и pane.children () совершенно не связаны. Я знаю это, потому что вот область, которую я пытаюсь изменить:
username_field = tab.child_window(auto_id="usr_userid", control_type="Pane").child_window(auto_id="_textBox", control_type="Edit")
username_field.set_text(username)
он введет текст в правильное поле, но в другом диалоговом окне.
Я думаю, что я, возможно, достиг предела pywinauto, учитывая, что именно так была разработана программа, но я все еще думаю, что возможен обходной путь, но я не уверен, как этого достичь:
Когда меню открывается, оно порождает окно и фокусирует его. Я просто хочу сделать некоторые проверки в ожидании открытия окна и в ожидании фокусировки на клавиатуре (программа может быть очень медленной или очень быстрой в разы), но я не могу понять, как выбрать дочерний диалог без указания на первый взгляд случайный дескриптор (я попытался перебрать все вкладки и посмотреть, помечены ли там различные свойства как «включенные», «видимые», «активные»).
Вот вывод идентификатора элемента управления для диалогового окна, я просто не знаю, как провести различие между любым из диалогов.
Dialog - 'User Maintenance' (L352, T80, R1920, B1027)
['Dialog', 'User Maintenance', 'User MaintenanceDialog']
child_window(title="User Maintenance", auto_id="QViewForm", control_type="Window")
|
| Pane - '' (L352, T80, R1918, B1027)
| ['', 'Pane', '0', '1', 'Pane0', 'Pane1']
| child_window(auto_id="_dtApplication", control_type="Pane")
| |
| | Pane - '' (L352, T110, R1918, B1027)
| | ['2', 'Pane2']
| | child_window(auto_id="DTApplication_Fill_Panel", control_type="Pane")
| | |
| | | Pane - '' (L352, T110, R1124, B182)
| | | ['3', 'Pane3']
| | | child_window(auto_id="_dtWindow0", control_type="Pane")
| | | |
| | | | Pane - '' (L352, T110, R1123, B182)
| | | | ['4', 'Pane4']
| | | | child_window(auto_id="461788", control_type="Pane")
| | | | |
| | | | | GroupBox - ' ' (L352, T110, R1120, B182)
| | | | | [' ', ' GroupBox', 'GroupBox', 'GroupBox0', 'GroupBox1']
| | | | | child_window(title=" ", auto_id="_framePanel", control_type="Group")
| | | | | |
| | | | | | Pane - '' (L356, T126, R1119, B181)
| | | | | | ['5', 'Pane5']
| | | | | | child_window(auto_id="_frameGroup", control_type="Pane")
| | | | | | |
| | | | | | | Edit - ' User ID: ' (L357, T132, R418, B153)
| | | | | | | ['6', 'Edit', 'Edit0', 'Edit1']
| | | | | | | child_window(title=" User ID: ", auto_id="_label", control_type="Edit")
| | | | | | | |
| | | | | | | | Edit - '' (L357, T132, R418, B153)
| | | | | | | | ['7', 'Edit2']
| | | | | | |
| | | | | | | Pane - '' (L418, T132, R543, B153)
| | | | | | | ['8', 'Pane6']
| | | | | | | child_window(auto_id="usr_userid", control_type="Pane")
| | | | | | | |
| | | | | | | | Edit - '' (L418, T132, R543, B153)
| | | | | | | | ['9', 'Edit3']
| | | | | | | | child_window(auto_id="_textBox", control_type="Edit")
Резюме: я пытаюсь выбрать auto_id="_textBox", control_type="Edit"
, но в любое время может быть открыто более 3 диалогов этого окна, и я не могу узнать, какой из них выбран.
Edit:
Я заметил, что при смене вкладок кажется, что одно из этих значений меняется на отрицательное:
>>> pane.children(title='User Maintenance')
[<uiawrapper.UIAWrapper - 'User Maintenance', Dialog, 141765657>, <uiawrapper.UIAWrapper - 'User Maintenance', Dialog, -1460376553>]
>>> pane.children(title='User Maintenance')
[<uiawrapper.UIAWrapper - 'User Maintenance', Dialog, -1460376553>, <uiawrapper.UIAWrapper - 'User Maintenance', Dialog, 141765657>]
Что это за идентификатор, если не дескриптор?
Edit2: я нашел решение, которое работает, но я уверен, что должен быть лучший способ.
tab_handle = pane.children()[0].element_info._get_current_handle()
tab = pane.child_window(handle=tab_handle)
Кажется, что _get_current_handle () всегда работает для целевой вкладки, независимо от того, какой элемент в списке я выберу. Это, безусловно, работает на данный момент - учитывая, что, если кто-нибудь знает немного более элегантный способ, я бы хотел знать.