【问题标题】:How to script a button click based on Label or Identifier如何根据标签或标识符编写按钮单击脚本
【发布时间】:2019-05-17 14:17:41
【问题描述】:

我正在用 AppleScript 编写一个脚本,该脚本以在应用程序中按下按钮结束。然而,问题是按钮没有属性标题。我已经在它上面运行了 Accessibility Inspector 和 UI Browser,AXTitle 是

我可以通过按钮的编号来调用按钮,但是我团队中的每个人都根据他们自己的工作流程稍微不同地设置了这个应用程序,而且愚蠢的按钮根据窗口的位置有不同的识别号。该窗口可以是分离的弹出窗口,也可以附加到左侧或右侧的主应用程序窗口。所有三个选项都会产生不同的索引地址。


附加到左侧时的按钮索引:

tell application "System Events" to tell process "Application Name"
    click button 8 of splitter group 1 of front window of application 
    process "Application Name" of application "System Events"
end tell




附加到右侧时的按钮索引:

tell application "System Events" to tell process "Application Name"
    click button 9 of splitter group 1 of front window of application 
    process "Application Name" of application "System Events"
end tell




窗口分离和浮动时的按钮索引:

tell application "System Events" to tell process "Application Name"
    click button 8 of front window of application process "Application    
    Name" of application "System Events"
end tell




位置之间的常量是按钮标签和按钮标识符,但我无法让脚本编辑器根据标识符或准备响应来识别按钮。我不知道这是不可能的还是我只是写错了代码。

当我尝试使用标签或标识符时出现错误

click button "Prepared Response" of front window

脚本错误系统事件出错:无法获取进程“应用程序名称”窗口 1 的按钮“准备响应”。

click button "_NS:667" of front window

脚本错误系统事件出错:无法获取进程“应用程序名称”窗口 1 的按钮“_NS:667”。

click button with "Prepared Response" of front window

语法错误应为“into”、变量名、类名、其他参数名称或属性,但找到“”。

click button with label "Prepared Response" of front window

语法错误 应为“given”、“with”、“without”、其他参数名称等,但找到“”。


唯一的两个限制是代码必须是 AppleScript - 而不是 Javascript - 并且我不能要求我的团队成员安装应用程序

【问题讨论】:

  • 它是什么应用程序?除了AXTitle之外的其他属性或属性呢?
  • 这是一个内部专有应用程序,我的 NDA 阻止我在公共论坛上命名。它具有标签、启用、框架、帮助、标识符、位置、角色和大小。没有标题也没有价值。
  • 这些是属性,它们听起来像是窗口的属性,而不是按钮。不要忘记还有属性,它们与属性不同。运行tell app "System Events" to tell process AppName to return the {name, value} of every attribute of button 8 of splitter group 1 of window 1 行(或任何适用于您的系统的参考),这将为您提供可用于标识按钮的属性的名称和值列表。您可以对 every property 执行相同的操作(descriptionrole description 有时具有有用的值)。
  • {{"AXRole"、"AXHelp"、"AXEnabled"、"AXWindow"、"AXSize"、"AXTitle"、"AXRoleDescription"、"AXTopLevelUIElement"、"AXFocused"、"AXDescription"、 "AXParent", "AXPosition", "AXFrame", "AXIdentifier"}, {"AXButton", "Responses", true, 应用程序“系统事件”的应用程序进程“AppName”的窗口“电子邮件”, {31, 19} , "", "button", 缺失值, false, "Response", 应用程序 "System Events" 的应用程序进程 "AppName" 的窗口 "Email", {1693, 105}, {1693, 105, 1724, 124}, "_NS:667"}}
  • AXHelpAXDescriptionAXIdentifier 每个看起来都是唯一标识该按钮的可行候选者。我看到您尝试使用"_NS:667",但您这样做不正确,因为您尝试将其替换为按钮的名称,但您不能这样做。您可以这样做:tell app "System Events" to tell process AppName to tell window 1 to get the first button whose value of attribute "AXIdentifier" = "_NS:667",或者与其他两个属性类似,这取决于您认为最好使用的属性。那么这应该适用于所有系统,无论如何。

标签: applescript


【解决方案1】:

这是一种可能适合您的方法。

AppleScript 能够在每次运行脚本时更改 property 值并保存这些新的 property 值。但是,如果脚本在任何时候重新编译,那些已更改的新 property 值将丢失并恢复为原始值。

在下面的代码中,我设置了变量 property launchCount : 0 并在接下来的几行中设置了另一个变量 set launchCount to launchCount + 1 。所以每次脚本运行时,property launchCount : 0 都会从 0 变为 1,然后是 2,然后是 3,以此类推...

这种方法的目的是,对于第一次运行脚本的每台计算机,都会出现一个choose from list 对话框,要求用户选择他们的窗口位置。然后该选择将存储在另一个变量property windowIsLocated 中。接下来是使用条件子句设置处理程序...例如:if windowIsLocated is this then do that else if windowIsLocated is that then do this

property launchCount : 0
property windowIsLocated : missing value

set launchCount to launchCount + 1

set theList to {"Window Attached To Left", "Window Attached To Right", "Window Is Floating"}

if launchCount is 1 then
    set windowLocation to choose from list theList ¬
        with title "Window Location" with prompt ¬
        "Please Choose The Location Of Your Window" OK button name ¬
        "OK" cancel button name ¬
        "Cancel" multiple selections allowed false ¬
        without empty selection allowed
    set windowIsLocated to item 1 of windowLocation
end if

clickTheButton() -- use this anywhere in your script to click the button 

to clickTheButton()
    if windowIsLocated is "Window Attached To Left" then
        tell application "Application Name"
            activate
            repeat until frontmost
                delay 0.1
            end repeat
        end tell
        tell application "System Events" to tell process "Application Name"
            click button 8 of splitter group 1 of front window
        end tell
    else if windowIsLocated is "Window Attached To Right" then
        tell application "Application Name"
            activate
            repeat until frontmost
                delay 0.1
            end repeat
        end tell
        tell application "System Events" to tell process "Application Name"
            click button 9 of splitter group 1 of front window
        end tell
    else if windowIsLocated is "Window Is Floating" then
        tell application "Application Name"
            activate
            repeat until frontmost
                delay 0.1
            end repeat
        end tell
        tell application "System Events" to tell process "Application Name"
            click button 8 of front window
        end tell
    end if
end clickTheButton

阅读了您帖子中的所有 cmets,我决定添加一个 .gif,演示使用 Automator.app 的“Watch Me Do”来记录我单击系统偏好设置中的一些按钮,然后将这些操作复制到脚本编辑器并使用该代码的元素用于识别按钮和窗口等。

【讨论】:

  • 这太棒了,解决了我的问题。我能够在同一个脚本中使用您的代码两次——一次用于我描述的部分,一次用于我没有意识到一旦我越过第一个障碍就会发生的部分。但是两个实例都能够使用相同的 windowIsLocated 变量。现在,如果只有某种方法可以关闭 Popover 窗口,但我所有的研究表明 AppleScript 无法关闭 Popover。
  • @Michel 请记住,我的解决方案中的代码可能会更短。不知道应用程序名称或查看您的整个脚本或应用程序窗口的任何屏幕截图,很难提供“现场”解决方案。
  • 我明白了。我希望我可以把整个脚本都扔掉,因为这样会让事情更容易排除故障,但是识别信息太多了。发布它是我的老经理所说的“限制职业生涯的举动”。哈。
【解决方案2】:

我发现get properties 对调试很有用:

tell application "System Events" to tell process "Application Name"
  get properties of every UI element of front window
end tell

你会得到一堆垃圾,几乎所有的垃圾都可能是(missing value) 用于你尝试编写脚本的应用程序。但是有的会填,比如description。弄清楚这一点后,您可以通过以下方式消除所有噪音:

tell application "System Events" to tell process "Application Name"
  get description of every UI element of front window
end tell

但是,UI 元素是嵌套的。例如,您不会获得工具栏按钮,您可能只会获得 "toolbar" 作为第二个元素的描述。不是很有用...

要获取工具栏按钮,您可以:

tell application "System Events" to tell process "Application Name"
  get description of every UI element of toolbar 1 of front window
end tell

从那里,您应该可以轻松找到所需的工具栏按钮。然后就很简单了:

tell application "System Events" to tell process "Application Name"
  repeat with uiElement in UI elements of toolbar 1 of front window
    if description of uiElement is "Do The Thing" then
      click uiElement
    end if
  end repeat
end tell

【讨论】:

    猜你喜欢
    • 2019-06-27
    • 2014-06-24
    • 2012-09-02
    • 1970-01-01
    • 2021-02-12
    • 1970-01-01
    • 2021-11-16
    • 2015-07-17
    • 2015-12-20
    相关资源
    最近更新 更多