事件处理器(Handler)是AppleScript的专有名词,可以理解为其他程序语言中得函数(Function,如:C语言)、方法(Method,如:Java)或者是子程序(Subroutines)。 简单来说,事件处理器在AppleScript中的价值就是减少大段类似代码,提高代码可复用性。 可以借用事件处理器来编写超酷的“Drag & Drop App”以及“文件夹脚本”。
基本的事件处理器
事件处理器是一段代码的集合,通过呼叫它的名称(即“调用”)来执行其中的具体代码。 事件处理器如果没有被调用,那么其中的代码将永远不可能被执行。最基本的事件处理器定义和调用过程,如下:
on HelloWorld() --定义开始
display dialog "Hello,world" --事件处理器中具体要执行的代码
end HelloWorld --定义结束
HelloWorld() --调用
其中: HelloWord 是这个事件处理器的名称,请特别留心名称后面的括号,正式这对括号,才把变量名称和事件处理器名称区分开来。
又一个非常重要的问题需要强调:任何事件处理器无法在Tell语句块内直接被调用,如果确实需要调用,应该使用HelloWorld() of me
。请记住“of me”
带参数的事件处理器
所谓事件处理器,应当是智能的---它应可以根据不同的场景根据同样的规则做出不同的响应。 我们可以通过“参数”把场景告诉事件处理器。 AppleScript提供了两种参数格式,位置参数(Positional Parameters)和 标签参数(Labeled Parameters)。
位置参数: 是和其他语言类似的常规参数格式。
标签参数: 是为了体现AppleScript贴近生活语言而设计的。 不过,如果没有处理好,标签参数将会非常的悲剧。因此建议:少使用标签参数。
位置参数
根据参数出现的前后顺序来区分。 要使用位置参数,应当将变量名称(不应和现有名称重复,应该取一个新名称,仅供事件处理器内部使用,体现“局部变量”的概念)置于括号内。至于参数个数没有限制,多个参数以逗号分隔。如:
on Hello(somebody,howLong) --定义开始
display dialog somebody giving up after howLong
--该对话框将在指定时间后自动消失
end Hello --定义结束
Hello("Apple",2)
Hello("Microsoft",1)
Hello("User",3)
上面的代码以somebody和t作为参数传递给名为“Hello”的事件处理器。 对于有参数的事件处理器,调用时必须给出设定数量参数。**不同于严谨的高级语言,AS中得参数不需要指出参数类型,直接写变量名称即可。
标签参数
对于英语好的人非常有帮助,因为它让代码看起来就像是日常对话。 此外使用标签参数可以不按照参数本来的顺序,即使颠倒顺序,AS也能正确运行。实现与上面位置参数示例相同功能,标签参数如下:
on Hello to somebody for howLong --定义开始
display dialog somebody giving up after howLong
end Hello --定义结束
Hello to "Apple" for 2 --调用
Hello for 1 to "Microsoft" --颠倒顺序也可以正确执行
Hello to "User" for 3
AppleScript允许使用很多介词来“有意义”地区分各个参数。包括about
,above
,against
,apart from
,around
,aside from
,at
,below
,beneath
,beside
,between
,by
,for
,from
,given
,instead of
,into
,on
,onto
,out of
,over
,since
,thru(or through)
,under
等。 但是,每个介词只能出现一次。
返回值
事件处理器不仅可以处理,也可以告诉你它做了什么。 和其他编程语言类似,AS也使用return关键字。
on add(x,y)
set answer to (x + y)
return answer
end add
display dialog add(1,2) --获取add处理器的返回值
不仅可以return一个变量(代码:return aVarName),也可以单独使用return来结束事件处理器运行。
run和open事件处理器
AS为脚本应用程序(Script Application)提供了一些特殊的事件处理器。 包括run
,open
,quit
和idle
。使用起来和自定义的事件处理器一样,“on run”和“end run”。请注意:如果直接运行脚本,它们通常不会正常工作,只有将脚本保存为“应用程序”后,它们才能够正确运行。
run
run是一个默认的事件处理器,它是脚本运行的入口,任何不在其他事件处理器里的代码都隶属于run事件处理器。 通常我们不需要、也没有必要显式声明run事件处理器。 请记住:如果你显式声明了run,那么不能有任何代码位于事件处理器外,即所有代码必须位于你的事件处理器中或者是run事件处理器中。
open
open对于AppleScript开发者来说是非常有用的,它可以实现超酷的“Drag & Drop App”(使用拖放实现某些功能的程序),它仅仅对于保存为“应用程序”的脚本有效。
open其实是一个Max OS的系统命令,一旦用户在Finder中把文件或文件夹拖放到某程序或脚本的图标上,它就立刻收到open这个系统命令,如果你得AppleScript脚本中包含了open事件处理器,那么它将会处理这个情况。
open事件处理器可以、通常也一定会添加参数(标签参数),如“on open aFile”,aFile是参数,告诉脚本什么东西被拖放到了它的图标上。
下面实例代码的功能是:*如果用户将文件或者文件夹,拖放到脚本程序图标上,脚本会打开“文本编辑”(TextEdit)软件,并列出所拖放的文件的完整路径列表:
on open names
set pathNamesString to "" --首先设定一个空的文本
repeat with i in names
--在这个循环中,处理了每个被拖放到程序图标上的文件
--所做的工作就是记录下文件路径并加上回车,添加到本来的文本中
set iPath to (i as text)
set pathNamesString to pathNamesString & iPath & return
end repeat
--将记录下来的文件路径列表写入到文件
tell application "TextEdit"
set paragraph 1 of front document to pathNamesString
end tell
return
end open
再次强调:为了让脚本按照预想地工作,必须将它保存为“应用程序”,然后把文件拖放到该图标上。留意一下它的图标,看起来和一般的脚本没什么区别,但是它有个小箭头! 显示它是一个很牛的“Drag & Drop App”
保持打开的脚本应用程序
要实现本节的功能,请确保将脚本存储为应用程序,并勾选“保持打开”
,如下图。
为实现脚本“保持打开”,我们经常用到两个预设事件处理器:idle
和 quit
。
idle
这个事件处理器用于处理应用程序空闲时的后台任务,它具有循环的功能,只要不退出或者有其他任务,它就会隔一段时间自动执行其中的代码一次。其默认时间间隔是30秒,我们可以通过“return n
”命令来控制时间间隔,如“return 10” ,告诉AppleScript每隔10秒执行一次Idle中的任务。
quit
它用于处理用户手动退出保持运行的程序时要执行的任务。 其中,必须包含有“continue quit”命令,否则程序将不可能正常退出。 也就是说,即使触发了quit事件处理器,该保持打开的应用程序也不一定会退出。 应用程序将在执行“continue quit”命令时退出。
关于保持打开的脚本应用程序,示例如下:
on idle
beep 2 --蜂鸣两声
display dialog "程序正在运行" giving up after 1
return 5 --设定每隔5秒执行一次
end idle
on quit
display dialog "真的要退出?" buttons {"是的","不"} --询问是否退出
if button returned of result = "是的" then
continue quit --只有这个命令才会让它真正退出
end if
end quit
再次提示:如果直接从AppleScript编辑器中运行,将看不到结果,请保存后双击该程序运行。
文件夹操作
Finder右键菜单中得“文件夹操作”(Folder Action)命令,当文件或文件夹发生更改时,“文件夹操作”就会被激活。 这里的“文件夹操作”其实就是AS脚本,它们存储在“资源库\Scripts\Folder Action Scripts\”(或者用户资源库下相应的)文件夹中
。 需要在相应文件夹的右键菜单中激活文件夹操作。
关于编写自己的文件夹操作脚本,我们可以在AppleScript字典Standard Addition-Fold Actions中找到,里面有5个命令,通过事件处理器的方式,我们可以编辑对应命令。 这5个命令都有很多参数可选,示例:
on adding folder items to theFolder after receiving theItemList
--发现文件夹添加文件就弹出对话框,显示有几个文件添加了
display dialog ((count theItemList) & "个项目被添加到了该文件夹")
as text buttons {"好","立即查看"}
--选择立即查看则打开文件夹
if button returned of result = "立即查看" then
tel application "Finder"
open theFolder
end tell
end if
end adding folder items to
要使用这个脚本,首先需要将脚本保存到上文所述的指定位置,然后右击想要执行操作的文件夹,选择“文件夹操作设置”,按照屏幕提示选择你所编写的脚本。
文件夹操作的缺点是运行速度较慢,好处是不影响系统使用。可以编写一个脚本来监视重要的文件夹,将各种操作写入到文件,而用户全然不知有个脚本正在记录一举一动。