我正在尝试编写一个脚本,该脚本应该在每个包含特定静态文本的对话框上按下OK按钮:
tell application "System Events"
set theProcesses to application processes
repeat with theProcess from 1 to count theProcesses
tell process theProcess
repeat with x from 1 to count windows
set texts to static text of window x
repeat with t from 1 to (count texts)
if (static text t of window x whose value is "Particular text") then
click first button whose value is "OK" of window x
end if
end repeat
end repeat
end tell
end repeat
end tell
此脚本未执行。 if语句出了点问题。
答案 0 :(得分:2)
你必须检查
if (value of static text t of window x is "Particular text")
如果“确定”按钮不存在,则需要try
块来忽略错误。
tell application "System Events"
set theProcesses to application processes
repeat with theProcess from 1 to count theProcesses
tell process theProcess
repeat with x from 1 to count windows
set texts to static text of window x
repeat with t from 1 to (count texts)
if (value of static text t of window x is "Particular text") then
try
click (first button of window x whose value is "OK")
end try
end if
end repeat
end repeat
end tell
end repeat
end tell
答案 1 :(得分:1)
作为一种替代方法,从理论上说,如果你有大量的进程,窗口和文本对象循环 - 可能会更快地抓住所有东西。这可以在一个单行中完成,但将其分解为单独的行不会牺牲任何速度,并提供更容易阅读的代码块:
tell application "System Events"
set P to a reference to every process
set W to a reference to every window of P
set S to a reference to (static texts of W whose value is "Particular text")
set C to a reference to value of attribute "AXParent" of S
set B to a reference to (buttons of C whose name is "OK")
repeat with _b in B
click _b
end repeat
end tell
用一些粗略的解释来打破它:
P
:包含对每个流程的引用。因为它是每个进程的引用,而不仅仅是进程本身,AppleScript不需要花费任何精力来确定这些进程到底是什么。它基本上存储了稍后在变量P
中执行此操作的指令。
W
:是对每个流程的每个窗口的引用。到目前为止,这两行相当于前两个repeat
循环,但到目前为止尚未执行任何计算,而您的脚本将经历(count windows
×count processes
次计算)。
S
:是对符合所需值的所有静态文本的引用。对于所有意图和目的,这“绕过”单独循环它们的需要,并立即抓取正确的(实际上,仍然执行循环 ,但它在更深的代码级别执行,它比AppleScript执行的任何循环花费的时间少一些。
C
:包含静态文本的父级,即包含所述文本的窗口。 (C
代表容器 = 父)
B
:最终是包含特定静态文本的每个窗口的所有“OK”按钮的集合。它是对它们的引用,所以,再次,可以一次性抓住它们,避免repeat
循环。
最后,要点击B
中的按钮,我们会进行第一次实际计算,然后循环遍历B
。但是,B
仅包含需要单击的按钮,因此不会浪费迭代,因此不需要try...end try
块。
由于B
中的每个按钮都是通过变量_b
访问的,因此这是AppleScript将所有这些引用放在一起的地方,并执行检索按钮所需的必要(并且只是必要的)计算,这可以等同于每个repeat
循环的一次迭代。
虽然这已经是获取您需要点击的按钮的一种非常有效的方法,但我们可以过滤流程和窗口以进一步改进它:
tell application "System Events"
set P to a reference to (processes whose background only is false)
set W to a reference to (windows of P whose subrole is not "AXUnknown" and role is "AXWindow")
set S to a reference to (static texts of W whose value is "Particular text")
set C to a reference to value of attribute "AXParent" of S
set B to a reference to (buttons of C whose name is "OK")
repeat with _b in B
click _b
end repeat
end tell
正如我所提到的,另外一个优点是,这需要更少 - 如果有任何错误处理(运行早于MacOS 10.12的OS X版本的系统可能需要将repeat
循环包装在{{{} 1}}阻止;在MacOS 10.12及更高版本中,这不是必需的)。如果try
返回空结果,则会在脚本中需要try
块,这会导致first button of window x whose value is "OK"
抛出错误。在此处,click
仅包含名为“确定”的按钮(如果需要,可将B
更改为name
),因此value
始终可以点击。
然而,为了提高稳健性并满足早期系统的需要,在错误处理方面要考虑周到是好的做法:
click
因此,值得一提的是,您的脚本可能需要额外的错误处理,而不仅仅是单个 try
repeat with _b in B
click _b
end repeat
end try
块:单击“OK”按钮后,我的猜测是对话框消失了。发生这种情况时,它包含的所有静态文本对象都会随之消失,这意味着不完整的try
循环将抛出另一个错误。
感谢@user3439894测试OS X 10.8.6中的代码。