将tabcontrol项链接到对话框窗口?

时间:2019-07-03 18:30:35

标签: pywinauto

我正在尝试使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的“用户维护”项来控制和选择选项卡,并且可以修改“用户维护”对话框中的内容,但似乎找不到将它们链接在一起的任何内容。 / p>

我尝试了一些操作,例如循环浏览选项卡,并返回活动选项卡的索引:

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个以上的对话框,而且我无法知道哪个是所选项目。

编辑: 我注意到,交换标签时,这些值之一似乎变为负值:

>>> 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()始终可用于焦点选项卡,而不管我选择列表中的哪个项目。既然有的话,如果有人知道我想知道的一种更优雅的方式,它肯定会立即起作用。

0 个答案:

没有答案