如何用Python或Swift获取Finder中选中元素的屏幕坐标
解决方案:获取Finder选中元素的屏幕坐标
Python 实现(基于PyObjC)
依赖pyobjc库,通过macOS辅助功能(Accessibility)API获取元素位置:
- 安装依赖:
pip install pyobjc-core pyobjc-framework-AppKit pyobjc-framework-AXUIElement
- 核心代码:
import objc from AppKit import NSWorkspace, NSApplication from AXUIElement import AXUIElement, kAXSelectedChildrenAttribute, kAXPositionAttribute, kAXSizeAttribute def get_finder_selected_item_position(): # 获取Finder应用实例 workspace = NSWorkspace.sharedWorkspace() finder_app = workspace.runningApplicationsWithBundleIdentifier_("com.apple.finder")[0] finder_pid = finder_app.processIdentifier() # 初始化AXUIElement finder_element = AXUIElementCreateApplication(finder_pid) # 获取选中的子元素 selected_children = objc.pyobjc_id(AXUIElementCopyAttributeValue(finder_element, kAXSelectedChildrenAttribute, None)[1]) if not selected_children or len(selected_children) == 0: return None # 获取第一个选中元素的位置与尺寸 selected_item = selected_children[0] position = objc.pyobjc_id(AXUIElementCopyAttributeValue(selected_item, kAXPositionAttribute, None)[1]) size = objc.pyobjc_id(AXUIElementCopyAttributeValue(selected_item, kAXSizeAttribute, None)[1]) # 计算元素中心坐标(右键点击常用中心) x = position.x + size.width / 2 y = position.y + size.height / 2 # 转换为屏幕坐标系(macOS原点在左下角,需转成左上角) screen_frame = NSApplication.sharedApplication().mainScreen().frame() screen_y = screen_frame.size.height - y return (x, screen_y) # 调用示例 pos = get_finder_selected_item_position() if pos: print(f"选中元素屏幕坐标:({pos[0]}, {pos[1]})")
注意:运行前需在「系统设置 > 隐私与安全性 > 辅助功能」中给你的Python脚本/IDE授权。
Swift 实现
利用macOS Accessibility框架与AppKit:
- 导入必要框架:
import AppKit import Accessibility
- 核心函数:
func getFinderSelectedItemScreenPosition() -> CGPoint? { guard let finderApp = NSWorkspace.shared.runningApplications.first(where: { $0.bundleIdentifier == "com.apple.finder" }) else { return nil } let finderPID = finderApp.processIdentifier let finderElement = AXUIElementCreateApplication(finderPID) // 获取选中元素 var selectedChildren: AnyObject? let status = AXUIElementCopyAttributeValue(finderElement, kAXSelectedChildrenAttribute as CFString, &selectedChildren) guard status == .success, let children = selectedChildren as? [AXUIElement], !children.isEmpty else { return nil } let selectedItem = children[0] // 获取位置和尺寸 var position: AnyObject? guard AXUIElementCopyAttributeValue(selectedItem, kAXPositionAttribute as CFString, &position) == .success, let pos = position as? CGPoint else { return nil } var size: AnyObject? guard AXUIElementCopyAttributeValue(selectedItem, kAXSizeAttribute as CFString, &size) == .success, let sz = size as? CGSize else { return nil } // 计算中心坐标并转换为屏幕坐标系 let centerX = pos.x + sz.width / 2 let centerY = pos.y + sz.height / 2 guard let mainScreen = NSScreen.main else { return nil } let screenY = mainScreen.frame.height - centerY return CGPoint(x: centerX, y: screenY) } // 调用示例 if let position = getFinderSelectedItemScreenPosition() { print("选中元素屏幕坐标:(\(position.x), \(position.y))") }
注意:需在「系统设置 > 隐私与安全性 > 辅助功能」中给你的应用授权,否则会返回nil。
替代思路:无需坐标直接触发右键菜单
如果获取坐标遇到阻碍,可直接通过Accessibility API触发选中元素的右键菜单:
- Python:
AXUIElementPerformAction(selected_item, kAXShowMenuAttribute) - Swift:
AXUIElementPerformAction(selectedItem, kAXShowMenuAttribute as CFString)
内容的提问来源于stack exchange,提问作者Fedede
相关产品推荐
相关产品推荐

