【发布时间】:2019-12-04 15:04:38
【问题描述】:
在 JXA 中有没有一种方法可以通过一次调用从多个对象中获取多个属性?
例如,我想从菜单项中获取 name 和 enabled 属性,可以对每个单独的属性执行如下操作:
Application("System Events").processes.byName('Finder').menuBars[0].menuBarItems.name()
Application("System Events").processes.byName('Finder').menuBars[0].menuBarItems.enabled()
但是是否可以通过单个函数调用来获取它们?比如:
Application("System Events").processes.byName('Finder').menuBars[0].menuBarItems.select('name', 'enabled')
我知道,我可以遍历 menuBarItems 并从 .properties() 方法中收集属性,但是这种方法太慢了,这就是我寻找其他选项的原因。
更新
我正在寻找更好的性能,而不是更好的语法,即我希望在一次调用 System Events 时检索属性。
【问题讨论】:
-
不,虽然 Apple 事件 IPC 和 SQL 都是基于查询的,但没有直接等效于 SQL 的
SELECT a,b,c,… FROM…。单个 Apple 事件可以从多个对象中获取单个属性,但不能同时获取多个属性。 (您始终可以从多个对象中获取properties属性,尽管这可能有其自身的性能开销。)This 可能有助于澄清(警告各种 AE 功能在 AppleScript 和节点自动化中正常工作但在 JXA 中被破坏)。 -
@foo 我也得出一个结论,即这是不可能的,但我认为也许我遗漏了一些东西,因为文档远非完美。感谢您确认
-
没有技术原因它无法完成,但 AppleScript 无法表达它,因此应用程序不提供它。你能做的最好的事情是
get name of <all-elements>,然后get enabled of <all-elements>,然后将这些列表压缩在一起,但是AS 和JXA 对此都很痛苦。例如在 Python 中,我会使用from appscript import *; ref = app('System Events').processes['Finder'].menu_bars[1].menu_bar_items; zip(ref.name(), ref.enabled()),它只在两个 Apple 事件中提供[('Apple', True), ('Finder', True), ('File', True), ('Edit', True),…]。但我认为 CJK 的 C API 解决方案会更快。 -
当然,另外一个警告是,任何直接操作 GUI 控件的代码都不可避免地是棘手的、脆弱的、不太便携的,并且涉及安全性的 PITA 不断增加。您永远不会说您要解决的问题是什么,但如果它可以在不通过系统事件或较低级别的辅助功能 API 借助 GUI 脚本的情况下完成,那么几乎可以肯定最好这样做。
-
@foo 这是 UI 测试,我同意它是 PITA :)
标签: macos applescript osascript javascript-automation