6 votes

Bogue de la barre de progression AppleScript : comment empêcher le dialogue de progression de s'attarder ?

Le bogue :

Lorsque la fonction dialogue de progression est suivie d'une boîte de dialogue, la boîte de dialogue de progression s'attarde toujours, même si toutes les étapes de progression sont terminées et que la barre de progression est pleine. Il s'attardera jusqu'à ce que le script ait été annulé, jusqu'à ce que le script se soit achevé, ou jusqu'à ce qu'il n'y ait plus de dialogue dans le script.

Ce bogue ne peut être constaté lors de l'exécution du code à partir de script Editor.app, car, dans script Editor, une boîte de dialogue de progression n'apparaît pas. Au lieu de cela, un indicateur de progression en forme de tarte est intégré au bas de la fenêtre script.


Comment reproduire le bogue :

Enregistrer l'AppleScript suivant code sous la forme d'un fichier .app :

(Le fichier doit être un fichier .app, car les fichiers .scpt ne peuvent pas afficher les boîtes de dialogue de progression).

set n to 5

set progress total steps to n
set progress description to "Script Progress"
set progress additional description to "Additional description"

repeat with i from 1 to n
    delay 0.1
    set progress completed steps to i
end repeat

display dialog "The progress dialog should be gone at this point."

Au lancement de l'application, vous verrez ce qui suit :


La question :

Existe-t-il une solution pour forcer le dialogue de progression à se fermer une fois qu'il est terminé, de sorte que des dialogues supplémentaires puissent être placés après le dialogue de progression, sans que ce dernier soit toujours visible ?


Ce que j'ai essayé :

J'ai essayé d'aborder le problème en interprétant la boîte de dialogue de progression simplement comme une "fenêtre" de l'application.

Si vous exécutez le code suivant dans un fichier AppleScript distinct, alors que les deux boîtes de dialogue de ProgressBarTest.app sont à l'écran (comme dans la capture d'écran ci-dessus) :

tell application "System Events"
    set allWindows to name of window of processes whose visible is true
end tell 

return allWindows

vous apprendrez que ProgressBarTest.app a 2 "fenêtres" ouvertes. Les titres de ces fenêtres sont les suivants :

{"", "ProgressBarTest.app"}

La première fenêtre de cette liste fait référence à la display dialog dialogue. La deuxième fenêtre de cette liste, intitulée ProgressBarTest.app est le dialogue de progression.

J'ai ensuite essayé de fermer cette "fenêtre" de dialogue de progression en utilisant AppleScript (comme on peut le faire pour n'importe quelle fenêtre d'application standard). Mais le code suivant :

tell application "System Events" to tell process "ProgressBarTest.app"
    if exists window "ProgressBarTest.app" then
        close window "ProgressBarTest.app"
    end if
end tell

donnera à l'utilisateur un message d'erreur. Le texte de ce dialogue d'erreur est le suivant :

script Erreur

System Events a reçu une erreur : la fenêtre "ProgressBarTest.app" du processus "ProgressBarTest.app" ne comprend pas le message "close".

Je me suis rapidement rendu compte que, si votre écran a le même point de vue que celui de la capture d'écran ci-dessus, vous ne pouvez même pas fermer manuellement la boîte de dialogue de progression. En effet, la boîte de dialogue display dialog a la priorité sur la boîte de dialogue d'avancement ; la boîte de dialogue display dialog grise" (c'est-à-dire qu'elle désactive) tous les boutons de la boîte de dialogue de progression.

Ainsi, pour en tenir compte, dans le code de ProgressBarTest.app, j'ai ajouté une fonction delay 5 directement au-dessus de la display dialog "The progress dialog should be gone at this point." ligne. Je voulais voir si je pouvais fermer avec succès le dialogue de progression, si celui-ci était le seul dialogue actif de l'application.

J'ai essayé le code suivant :

tell application "System Events" to tell process "ProgressBarTest.app"
    if exists window "ProgressBarTest.app" then
        click button 1 of window "ProgressBarTest.app"
    end if
end tell

Dans le code ci-dessus, button 1 se réfère à la Stop qui se trouve dans la boîte de dialogue de progression. (Vous pouvez également utiliser button -4 ou button 0 pour faire référence à ce même bouton).

La bonne nouvelle, c'est que ce code a réussi à fermer la boîte de dialogue de progression !

La mauvaise nouvelle, cependant, c'est que lorsque la boîte de dialogue de progression Stop est pressé, au lieu de fermer uniquement la boîte de dialogue de progression, le bouton ensemble du script est annulée. Cette situation n'est évidemment pas souhaitable.

La racine du problème est que la boîte de dialogue de progression ne contient pas de "x" rouge ; le bouton circulaire le plus à gauche dans la barre supérieure de cette boîte de dialogue est toujours grisé. En d'autres termes, il n'existe aucun moyen de fermer manuellement la boîte de dialogue de progression sans mettre fin prématurément au script.

Ce problème est donc plus difficile à résoudre que je ne le pensais.

Il semble que le résultat que je souhaite obtenir soit impossible à atteindre.


OS X El Capitan, version 10.11.6.


5voto

wch1zpink Points 6067

Fonctionne pour moi sur la dernière version de MacOS Big Sur

MISE À JOUR

MEILLEURE SOLUTION

Si vous placez le display dialog à l'intérieur d'un System Events tell block puis envelopper le ignoring application responses autour de cette commande display dialog la commande progress indicator terminera sa tâche sans attendre l'intervention de la display dialog pour être rejetée.

En ignoring application responses ne fonctionnera que si elle est placée à l'intérieur de l'interface de l'application. tell block

set n to 50

set progress total steps to n
set progress description to "Script Progress"
set progress additional description to "Additional description"

repeat with i from 1 to n
    delay 0.1
    set progress completed steps to i
end repeat

tell application "System Events"
    activate
    ignoring application responses
        display dialog "The progress dialog should be gone at this point."
    end ignoring
end tell

enter image description here



ANCIENNE SOLUTION 1

set n to 5

set progress total steps to n
set progress description to "Script Progress"
set progress additional description to "Additional description"

repeat with i from 1 to n
    delay 0.1
    set progress completed steps to i
end repeat
return
quit

on quit
    activate
    display dialog "The progress dialog should be gone at this point."
    continue quit -- allows the script to quit
end quit

Voici un moyen d'exécuter quelques boucles répétitives avant que le script ne s'arrête

set n to 5

set progress total steps to n
set progress description to "Script Progress"
set progress additional description to "Additional description"

repeat with i from 1 to n
    delay 0.1
    set progress completed steps to i
end repeat
return
quit

on quit
    activate
    display dialog "The progress dialog should be gone at this point."
    repeat 5 times
        my get_my_IP()
        my screenCaptureToDesktop()
        delay 1
    end repeat
    continue quit -- allows the script to quit
end quit

on get_my_IP()
    activate
    tell current application to display dialog (do shell script "curl ifconfig.co") with icon 2 buttons "OK" default button 1 with title "Your Current IP Address Is.." giving up after 5 -- "curl ifconfig.io"    -- alternate
end get_my_IP

on screenCaptureToDesktop()
    do shell script "/usr/sbin/screencapture \"" & ¬
        POSIX path of (path to desktop as string) & ¬
        "Screen Shot " & (current date) & ".png\""
end screenCaptureToDesktop

ANCIENNE SOLUTION 2

En travaillant sur l'un de mes propres projets, j'ai eu un de ces moments "EUREKA". Voici une approche complètement différente de mon code dans la SOLUTION 1. L'approche ici était d'envelopper la plupart de mon code dans des objets script ou des gestionnaires, puis d'appeler ces objets selon les besoins. Dans cette solution, j'ai sauvegardé ce script en tant qu'application ouverte, avec des gestionnaires explicites d'exécution et d'inactivité. Une partie du code s'exécute au lancement de l'application, mais la plupart des commandes sont exécutées dans le gestionnaire d'inactivité.

Je pense que cette solution est plus prometteuse que la SOLUTION 1.

global allFiles, thisFile, theFileCount, ProgressBar, mainFolder, backupFolder, theDate

on run
    run ProgressBar
end run

on idle
    delay 0.2
    activate
    set theButton to button returned of (display dialog ¬
        "The progress dialog should be gone at this point." buttons {"QUIT", "CONTINUE"} ¬
        default button ¬
        "CONTINUE" with title ¬
        "BACKUP UTILITY" with icon 0 ¬
        giving up after 10)
    if theButton = "QUIT" then
        quit
    else if theButton = "" then
        quit
    else if theButton = "CONTINUE" then
        try
            run ProgressBar
        end try
    end if
    return 1
end idle

on quit
    --  Executed when the script quits
    continue quit -- allows the script to quit
end quit

script ProgressBar
    set mainFolder to choose folder with prompt ¬
        "PLEASE CHOOSE YOUR SOURCE FOLDER TO BACKUP"
    set backupFolder to choose folder with prompt ¬
        "PLEASE CHOOSE YOUR BACKUP DESTINATION FOLDER"
    set theDate to (current date) - (14 * days)

    tell application "Finder"
        set allFiles to entire contents of folder mainFolder as alias list
    end tell

    set theFileCount to count of allFiles

    set progress total steps to theFileCount
    set progress completed steps to 0
    set progress description to "Processing Files..."
    set progress additional description to "Preparing to process."

    repeat with theName from 1 to number of items in allFiles
        set this_item to item theName of allFiles
        tell application "Finder"
            duplicate this_item to backupFolder ¬
                with replacing
        end tell
        set progress additional description to ¬
            "Duplicating File " & theName & " of " & theFileCount & ¬
            " to folder " & backupFolder
        set progress completed steps to theName
    end repeat

    -- Reset the progress information
    set progress total steps to 0
    set progress completed steps to 0
    set progress description to ""
    set progress additional description to ""
end script

LesApples.com

LesApples est une communauté de Apple où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres utilisateurs d'appareils Apple, poser vos propres questions ou résoudre celles des autres.

Powered by:

X