gpt4 book ai didi

objective-c - 有没有办法从另一个自定义构建的应用程序或脚本监视和控制 macOS 应用程序?

转载 作者:行者123 更新时间:2023-12-03 18:07:24 24 4
gpt4 key购买 nike

这是一个普遍问题,我希望得到正确的方向。我希望能够监控 Mac 应用程序 Logic Pro X。这是一个专注于 DAW 控制的大学研究项目,我需要能够监控来自 DAW 的特定信息 - 主要是轨道和/的显示文本信息或其他方面。

控制方面并不是一个主要因素,因为这可以使用 MIDI 和/或键盘快捷键来实现。但想知道是否有人知道一种方法来监视另一个应用程序中一个应用程序的一些 GUI 文本信息。

在网上做了一些研究,但似乎找不到太多关于该主题的信息。

我在基于 C 的编程方面做得不多,但对 Python 和 Javascript 非常了解,所以这将是我尝试学习 Objective-C 的下一个项目。

任何帮助将不胜感激。

编辑 - 我刚刚发现这个,Use AppleScript to list the names of all UI elements in a window (GUI scripting)

这种使用 AppleScript 的方法在这里可行吗?

编辑-Areas of the GUI needed

这是我需要访问的文本的屏幕截图实际上,我已经能够在 Python 中使用 atomacos 来访问所有这些内容,文本包含在正确按钮的 AXDescription 中。然而,这些并不总是位于层次结构中的同一位置,因此我必须忽略错误并找到正确的路径。我还在 while 循环中不断获取文本,如果我可以观察属性以查看它们是否发生变化,那就更好了。这是我用来获取轨道名称的 Python 代码,我还设法深入轨道内部以获取音频效果名称。

import atomacos

logic = atomacos.getAppRefByBundleId('com.apple.logic10')
for w in logic.windows():
title = w.AXTitle
try:
if title.split(' - ')[1] == 'Tracks':
window = w
except IndexError:
continue
for section in window.AXChildren:
if section.AXRoleDescription == 'group':
try:
if section.AXChildren[1].AXDescription == 'Tracks':
tracks = section.AXChildren[1].AXChildren[0].AXChildren[1].AXChildren[0].AXChildren[0]
except IndexError:
continue
except AttributeError:
continue

while True:
track_list = {}
for track in tracks.AXChildren:
try:
for item in track.AXChildren:
try:
if item.AXRoleDescription == 'text field':
track_list[item.AXDescription] = item
except AttributeError:
continue
except atomacos.errors.AXErrorIllegalArgument:
continue
track_list.keys()

except AttributeError:
continue

最佳答案

这是一个示例 GUI 脚本,向您展示如何可靠地找到您标记的两个区域,并收集您想要的信息。我已经展示了如何找到“轨道”区域和“混音器区域”,但我只深入到“轨道”区域,您可以为您提供工作示例。如果您在拼凑其他区域时遇到困难,请告诉我,我会添加更多内容。

tell application "Logic Pro X" to activate

tell application "System Events"
tell process "Logic Pro X"
tell window "Untitled - Tracks"
(*
the following lines find the main 'tracks' group and the 'mixer' group, by looking for
stable features of their respective toolbars. the first looks for the
'Horizontal Zoom' slider, the second for the 'Wide Channel Strips' radio button.
the doubled 'whose' queries look confusing, but basically they say "Find the group
whose first group is a toolbar, whose last (slider's/radiobutton's) description is...
Once we have those, we can reliably find these area, regardless of whether other groups
are opened or closed"
*)
set main_track_group to first group whose its (first group whose role description is "Toolbar")'s last slider's description is "Horizontal Zoom"
try
set mixer_group to first group whose its (first group whose role description is "Toolbar")'s last radio group's last radio button's description is "Wide Channel Strips"
on error
-- mixer group is not open, so open it
keystroke "x"
delay 2
set mixer_group to first group whose its (first group whose role description is "Toolbar")'s first radio group's last radio button's description is "Wide Channel Strips"
end try

tell main_track_group
set track_group to first group whose role description is not "Toolbar"
tell track_group
tell first splitter group's second splitter group's first scroll area's first group
(*
And here we're at the list of tracks. Tracks can be addressed by index, like so:
*)
set track_item to third group
(*
or you can find them by name, with a little trickery. The double 'whose'
command is a little hard to parse, but it means "Find the first group that has a
text field element with the descrition 'Bass'"
*)
set track_item to first group whose its (first UI element whose role description is "text field")'s description is "Audio Track"
tell track_item
(*
once you have the track, you can access and set any values you could
normally see or set in the interface, by finding the relevent UI element.
all of these ui elements have their names in the 'description'
field. examples:
*)
-- log a list of all the visible UI elements
log (get description of every UI element)
-- get mute checkbox
set mute_check to first UI element whose role description is "checkbox" and description is "Mute"
-- log current state of the checkbox
log (get value of mute_check)
-- click the checkbox to toggle its state
click mute_check
end tell
end tell
end tell
end tell
end tell
end tell
end tell

如果您想随着时间的推移不断对这些进行采样,那么最好的选择是创建一个带有空闲处理程序的保持打开状态的应用程序。其模板是这样的:

global main_track_group, mixer_group -- global variables are available everywhere in the script

on run
(*
use this area to initialize stuff. In particular, initialize the two group variables
here so that you only have to do it once; whose commads are slow and expensive
*)
end run

on idle
(*
use GUI scripting to extract the values here. the return value (below) is the idle time, in seconds: e.g. 'return 1' means that this hnalder will be called once a second. make it as small as you need to get the info you want, but not so small that this app is eating up processing time'
*)
return 1
end idle

on quit
(*
do whatever cleanup you need to do here
*)
continue quit
end quit

将其保存为应用程序,并选中运行处理程序后保持打开状态复选框。

关于objective-c - 有没有办法从另一个自定义构建的应用程序或脚本监视和控制 macOS 应用程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61976859/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com