1

我需要使用 JXA 以编程方式从 iTunes 下载应用程序。我做了以下事情:

var its = SystemEvents.processes.byName('iTunes');
delay(3);
its.windows[0].buttons.byName('Get').click();

没有选择任何元素。我试过点击按钮[0...7],但没有一个是“获取”按钮。我假设我需要的按钮在文档中,但 JXA 文档明确指出按钮元素是 Window 的子元素,而不是 Document 的子元素。关于如何点击正确按钮的任何想法?

4

1 回答 1

0

诸如按钮之类的“叶子”UI 元素将位于可能复杂的 UI 元素层次结构的底部,在 iTunes 中尤其如此。

为了让您了解一下,这里有一个免费应用程序的 App Store 页面上按钮的示例对象说明符Get(假设您已经确保该页面处于活动状态):

Application("System Events")
  .applicationProcesses.byName("iTunes")
    .windows.byName("iTunes")
      .splitterGroups.at(0)
        .scrollAreas.at(0)
          .uiElements.at(0)
            .groups.at(3)
              .buttons.at(0)

问题是这个对象说明符因页面而异,因此理想情况下,您只需将过滤器应用于所有UI 元素(通过窗口的entireContents属性)以检索感兴趣的按钮:

// Get an array of all UI elements in iTunes window.
uiElems = Application("System Events").applicationProcesses['iTunes']
           .windows[0].entireContents()

// Find all buttons whose description contains 'Get'.
btns = uiElems.filter(function(el) { 
  try {
    return el.role() == 'AXButton' 
           &&
           el.description().match(/\bGet\b/)
  } catch (e) {}
})

// Click on the 1st button found.
btns[0].click()

这里有一个问题:在我相当新的机器上,这大约需要 20 秒(!)。

我会想象一个.whose-style 过滤器会更快,但我无法让它在这种情况下工作,因为必须捕获异常 - 如上所述 - 但.whose似乎不支持嵌入式异常处理程序。

如果您愿意假设可以在其子树中找到按钮的层次结构中的较低级别,则可以大大加快速度:

// Get the group UI elements in one of which the 'Get' button is located.
grps = Application("System Events").applicationProcesses['iTunes'].
        windows[0].splitterGroups[0].scrollAreas[0].uiElements[0].groups

// Loop over groups
count = grps.length
for (i = 0; i < count; ++i) {
  // In the group at hand, find all buttons whose description contains 'Get'.
  btns = grps[i].entireContents().filter(function(el) { 
    try {
      return el.role() == 'AXButton' 
             &&
             el.description().match(/\bGet\b/)
    } catch (e) {}
  })
  // Exit loop, if a 'Get' button was found.
  if (btns.length > 0) break  
}

if (btns.length == 0) {
  console.log('ERROR: No "Get" button found.')
} else {  
  // Click on the 1st button found.
  btns[0].click()
}

这将在不到 1 秒的时间内运行。在我的机器上。


不幸的是,UI 自动化(GUI 脚本)是一项棘手的工作。

对于交互式探索,Xcode 附带了Accessibility Inspector开发人员工具,但使用它并非易事,尤其是在将发现转换为代码时。

于 2015-10-22T06:33:10.610 回答