0

我正在编写一个applescript 应用程序,它每5 分钟说一次。这将处于无限循环中。我的要求是,虽然它自启动以来一直运行 24x7,但下次当我单击应用程序图标时,它应该显示对话框以通过 3 个按钮之一获取用户输入。

我有 3 个按钮。

  • 暂停通知
  • 通知开启
  • 通知关闭

当代码处于无限循环时,我单击应用程序图标,对话框提示不会出现以通过上述 3 个按钮获取用户输入。如何解决?

global isSoundEnabled, isNotifEnabled

on run
    set isSoundEnabled to true
    set isNotifEnabled to true
    
    set theDialogText to "The curent date and time is " & (current date) & "."
    display dialog theDialogText buttons {"Pause", "Notif ON", "Notif OFF"} default button "Notif ON" cancel button "Pause" with icon caution
    
    if result = {button returned:"Notif ON"} then
        set isSoundEnabled to true
        set isNotifEnabled to true
        loop()
    else if result = {button returned:"Notif OFF"} then
        set isSoundEnabled to false
        set isNotifEnabled to false
    end if
end run

on loop()
    repeat while true
        set min to getMin()
        get min as integer
        #if (min mod 5) = 0 then
        if (min / 5) > 1 then
            set timee to getTimeInHoursAndMinutes()
            if isNotifEnabled then
                display notification timee
            end if
            if isSoundEnabled then
                say timee
            end if
            #delay 60
            #if isSoundEnabled is not 
        end if
        #exit repeat
    end repeat
end loop

我没有故意添加 getTimeInHoursAndMinutes() 和 getMin() 实现,因为它没有多大价值。

4

1 回答 1

2

如果您不给系统时间来处理事件,应用程序用户界面(菜单等)将被阻止,因此您希望避免长时间的重复循环。标准对话框是模态的,因此在显示它们时您通常也不能做其他事情。

重复显示标准对话框也可能是侵入性的,因为如果激活应用程序(以显示对话框),当前应用程序将切换,或者如果您不这样做,Dock 图标将开始弹跳。一些 AppleScriptObjc 可以用于其他类型的通知,但在本例中,我使用标准对话框。

我在下面的脚本中使用了一些 AppleScriptObjC 作为语音合成器,因为它可以在后台说话(同时显示一个对话框)。我也避免使用通知,因为这些需要在系统偏好设置中被允许。

底线是,当将应用程序保存为 时stay open,可以使用idle和处理程序 -在运行处理程序完成后重复调用处理程序(它使用计时器),并在双击应用程序时调用处理程序(或Dock 图标单击),因此您可以避免锁定 UI。例如:reopenidlereopen

use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "AppKit" -- for the speech synthesizer
use scripting additions

global isSoundEnabled, isNotifEnabled, defaultButton

on run -- initial setup
    set isSoundEnabled to true
    set isNotifEnabled to true
    set defaultButton to "Notif OFF" -- the default is set opposite the current setting
    getSettings()
end run

to getSettings()
    set theDialogText to "The curent date and time is " & (current date) & "."
    tell me to activate
    set theButton to button returned of (display dialog theDialogText buttons {"Quit", "Notif ON", "Notif OFF"} default button defaultButton with icon caution giving up after 10)
    if theButton is "Notif ON" then
        set isSoundEnabled to true
        set isNotifEnabled to true
        set defaultButton to "Notif OFF"
    else if theButton is "Notif OFF" then
        set isSoundEnabled to false
        set isNotifEnabled to false
        set defaultButton to "Notif ON"
    end if
end getSettings

on reopen -- application double-clicked or dock icon clicked
    getSettings()
end reopen

on idle -- after the run handler completes, is called repeatedly
    set giveup to 5 -- dialog will self-dismiss, although timing will be a little off if manually dismissed 
    set theTime to time string of (current date)
    if isSoundEnabled then -- AppleScriptObjC is used to speak in the background
        (current application's NSSpeechSynthesizer's alloc's initWithVoice:(missing value))'s startSpeakingString:theTime
    end if
    if isNotifEnabled then
        tell me to activate
        display dialog "The current time is " & theTime with title "Current time" buttons {"OK"} giving up after 5
    end if
    return 300 - giveup -- the number of seconds for next idle run (less the dialog giveup time)
end idle
于 2021-09-28T06:16:15.377 回答