如何获取窗口的 UI 元素?迅速

Posted

技术标签:

【中文标题】如何获取窗口的 UI 元素?迅速【英文标题】:How Get UI Elements of a Window? Swift 【发布时间】:2021-10-30 07:17:50 【问题描述】:

如何将此 AppleScript 代码翻译成 Swift ?

tell application "System Events" to tell process "Safari" to get UI elements of first window

我已经到达“Safari”的第一个窗口,但我不知道如何获取 UI 元素

let pid = NSWorkspace.shared.runningApplications.first(where: $0.localizedName == "Safari")?.processIdentifier
let appRef = AXUIElementCreateApplication(pid!)
var windows: AnyObject?
_ = AXUIElementCopyAttributeValue(appRef, kAXWindowsAttribute as CFString, &windows)
if let firstWindow = (windows as? [AXUIElement])?.first
    print(firstWindow)

【问题讨论】:

【参考方案1】:

您可以使用相同的AXUIElementCopyAttributeValue()查询窗口的孩子,以及孩子的孩子,等等。

我自己喜欢在现有类型上添加扩展,如果可能的话,为了更清晰:

extension AXUIElement 
    var children: [AXUIElement]? 
        var childrenPtr: CFTypeRef?
        AXUIElementCopyAttributeValue(appRef, kAXChildrenAttribute as CFString, &childrenPtr)
        return childrenPtr as? [AXUIElement]
    

然后您可以在代码中使用它:

if let firstWindow = (windows as? [AXUIElement])?.first
    print(firstWindow, firstWindow.children)

您可以更进一步,通过向扩展添加更多功能来简化AXUIElement 消费者代码:

extension AXUIElement 
    
    static func from(pid: pid_t) -> AXUIElement  AXUIElementCreateApplication(pid) 
    
    var windows: [AXUIElement]?  value(forAttribute: kAXWindowsAttribute) 
    
    var children: [AXUIElement]?  value(forAttribute: kAXChildrenAttribute) 
    
    func value<T>(forAttribute attribute: String) -> T? 
        var attributeValue: CFTypeRef?
        AXUIElementCopyAttributeValue(self, attribute as CFString, &attributeValue)
        return attributeValue as? T
    


let pid = ...
let app = AXUIElement.from(pid: pid!)
if let firstWindow = app.windows?.first
    print(firstWindow, firstWindow.children)

【讨论】:

以上是关于如何获取窗口的 UI 元素?迅速的主要内容,如果未能解决你的问题,请参考以下文章

Qt:子窗口中如何获取主窗体ui中的控件

js/jquery如何获取获取父窗口的父窗口的元素

统一3d。如何获取ui元素的屏幕或世界位置

请问qt中如何获取textEdit中内容?

如何使用 python 获取本机 mac 应用程序的 UI 元素?

jquery,iframe,如何在父窗口监听,子窗口发生改变时,父窗口获取子窗口的值