14 9月, 2016

事件处理器

内容纲要

事件处理器(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,quitidle。使用起来和自定义的事件处理器一样,“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

要使用这个脚本,首先需要将脚本保存到上文所述的指定位置,然后右击想要执行操作的文件夹,选择“文件夹操作设置”,按照屏幕提示选择你所编写的脚本。
文件夹操作的缺点是运行速度较慢,好处是不影响系统使用。可以编写一个脚本来监视重要的文件夹,将各种操作写入到文件,而用户全然不知有个脚本正在记录一举一动。

You may also like...

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注