Как сделать так, чтобы приложение, написанное с использованием AppleScript, открывало диалог каждый раз при нажатии на значок?
Я пишу приложение 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(), поскольку они не имеют особой ценности.
1 ответ
Пользовательский интерфейс приложения (меню и т. Д.) Будет заблокирован, если вы не дадите системе время для обработки событий, поэтому вы хотите избежать длинных повторяющихся циклов. Стандартные диалоговые окна являются модальными, поэтому вы также обычно не можете выполнять другие действия, пока они отображаются.
Многократное отображение стандартных диалоговых окон также может быть навязчивым, поскольку текущее приложение будет переключаться при активации приложения (чтобы отобразить диалоговое окно), или значок Dock начнет подпрыгивать, если вы этого не сделаете. Некоторый AppleScriptObjc можно использовать для других типов уведомлений, но в этом примере я остановился на стандартных диалогах.
Я немного схитрил в следующем скрипте, используя некоторый AppleScriptObjC для синтезатора речи, поскольку он может говорить в фоновом режиме (пока отображается диалог). Я также избегал использования уведомлений, поскольку они должны быть разрешены в системных настройках.
Суть в том, что при сохранении приложения как
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