Contrôle de la boîte de dialogue de progression

Etant donné que les outils de script partagent l'application, vous pouvez contrôler la boîte de dialogue de progression. Vous pouvez contrôler l'apparence de la boîte de dialogue de progression en sélectionnant la barre de progression par défaut ou par étape.

Pour en savoir plus sur la boîte de dialogue Progression, consultez la rubrique Fonctionnement de la boîte de dialogue de progression dans les outils de script

Le code suivant montre l'utilisation complète de la barre de progression par défaut et par étape. Copiez ce code dans votre éditeur Python, enregistrez-le, puis créez-lui un outil de script. L'outil de script dispose de deux paramètres Long en entrée, comme décrit dans les commentaires du code. Exécutez ensuite l'outil de script, en fournissant des valeurs différentes pour les paramètres (commencez avec n = 10 et p = 1, puis essayez n = 101 et p = 3).

'''
Demonstration script showing examples of using the progressor
 Parameters:
   n - number to count to (a good first choice is 10)
   p - interval to count by (a good first choice is 1)
The various time.sleep() calls are just to slow the dialog down
so you can view messages and progressor labels.
'''

import arcpy
import time

n = int(arcpy.GetParameterAsText(0))
p = int(arcpy.GetParameterAsText(1))

readTime = 2.5  # Pause to read what's written on dialog
loopTime = 0.3  # Loop iteration delay

arcpy.AddMessage("Running demo with: {0} by {1}\n".format(n, p))

# Start by showing the default progress dialog, where the
#  progress bar goes back and forth. Note how the progress label
#  mimics working through some "phases", or chunks of work that
#  a script may perform.
#
arcpy.SetProgressor("default", "This is the default progressor")
time.sleep(readTime)

for i in xrange(1, 4):
    arcpy.SetProgressorLabel("Working on 'phase' {0}".format(i))
    arcpy.AddMessage("Messages for phase {0}".format(i))
    time.sleep(readTime)

# Setup the progressor with its initial label, min, max, and interval
#
arcpy.SetProgressor("step",
                    "Step progressor: Counting from 0 to {0}".format(n),
                    0, n, p)
time.sleep(readTime)

# Loop issuing a new label when the increment is divisible by the
#  value of countBy (p). The "%" is python's modulus operator - we
#  only update the position every p'th iteration
#
for i in range(n):
    if (i % p) == 0:
        arcpy.SetProgressorLabel("Iteration: {0}".format(i))
        arcpy.SetProgressorPosition(i)
        time.sleep(loopTime)

# Update the remainder that may be left over due to modulus operation
#
arcpy.SetProgressorLabel("Iteration: {0}".format(i + 1))
arcpy.SetProgressorPosition(i + 1)

arcpy.AddMessage("Done counting up\n")
time.sleep(readTime)

# Just for fun, make the progressor go backwards.
#
arcpy.SetProgressor("default", "Default progressor: Now we'll do a countdown")
time.sleep(readTime)
arcpy.AddMessage("Here comes the countdown...")
arcpy.SetProgressor("step",
                    "Step progressor: Counting backwards from {0}".format(n),
                    0, n, p)
time.sleep(readTime)
arcpy.AddMessage("Counting down now...\n")

for i in range(n, 0, -1):
    if (i % p) == 0:
        arcpy.SetProgressorLabel("Iteration: {0}".format(i))
        arcpy.SetProgressorPosition(i)
        time.sleep(loopTime)

# Update for remainder
#
arcpy.SetProgressorLabel("Iteration: {0}".format(i - 1))
arcpy.SetProgressorPosition(i - 1)
time.sleep(readTime)
arcpy.AddMessage("All done")
arcpy.ResetProgressor()

Sélection d'un incrément adapté lorsque le maximum est potentiellement élevé

Il n'est pas rare d'écrire des scripts qui se répéteront un nombre inconnu de fois. Par exemple, votre script peut utiliser une commande SearchCursor pour itérer sur toutes les lignes d'une table, sans savoir à l'avance le nombre de lignes : votre script peut être utilisé avec des tables de toute taille, de plusieurs milliers de lignes à des millions de lignes. Incrémenter une barre de progression par étape pour chaque ligne d'une grande table génère un ralentissement des performances, et vous devez vous en prémunir.

Pour démontrer et évaluer les performances avec les barres de progression par étape, copiez le code ci-dessous dans votre éditeur Python, enregistrez-le, puis créez un outil de script. L'outil a deux entrées : un paramètre de table et un paramètre de champ. Exécutez l'outil de script avec des tables de différentes tailles, mais veillez à essayer une table ou une classe d'entités contenant au moins 10 000 lignes pour voir les différences de performances. (Vous pouvez également essayer d'exécuter l'outil en cours de processus et hors processus pour constater l'amélioration des performances lors de l'exécution en cours de processus.)

Le script exécute trois boucles distinctes et chaque boucle extrait toutes les lignes de la table. Les boucles diffèrent dans leur façon de mettre à jour la barre de progression par étape. La première et la deuxième boucle mettent à jour la barre de progression par étape par grands incréments, tandis que la dernière boucle incrémente la barre de progression par étape pour chaque ligne. Lorsque vous exécutez l'outil, vous verrez que l'exécution de cette dernière boucle est plus longue.

Vous pouvez employer les techniques figurant dans ce code pour vos outils de script.

'''
Demonstrates a step progressor by looping through records
on a table. Use a table with 10,000 or so rows - smaller tables
just whiz by.
   1 = table name
   2 = field on the table
'''

import arcpy
import time
import math

try:
    inTable = arcpy.GetParameterAsText(0)
    inField = arcpy.GetParameterAsText(1)

    # Determine number of records in table
    #
    record_count = int(arcpy.GetCount_management(inTable).getOutput(0))
    if record_count == 0:
        raise ValueError("{0} has no records to count".format(inTable))

    arcpy.AddMessage("Number of rows = {0}\n".format(record_count))

    # Method 1: Calculate and use a suitable base 10 increment
    # ===================================

    p = int(math.log10(record_count))
    if not p:
        p = 1
    increment = int(math.pow(10, p - 1))

    arcpy.SetProgressor(
        "step", "Incrementing by {0} on {1}".format(increment, inTable),
        0, record_count, increment)

    beginTime = time.clock()
    with arcpy.da.SearchCursor(inTable, [inField]) as cursor:
        for i, row in enumerate(cursor, 0):
            if (i % increment) == 0:
                arcpy.SetProgressorPosition(i)
            fieldValue = row[0]

    arcpy.SetProgressorPosition(i)
    arcpy.AddMessage("Method 1")
    arcpy.AddMessage("\tIncrement = {0}".format(increment))
    arcpy.AddMessage("\tElapsed time: {0}\n".format(time.clock() - beginTime))

    # Method 2: let's just move in 10 percent increments
    # ===================================
    increment = int(record_count / 10.0)
    arcpy.SetProgressor(
        "step", "Incrementing by {0} on {1}".format(increment, inTable),
        0, record_count, increment)

    beginTime = time.clock()
    with arcpy.da.SearchCursor(inTable, [inField]) as cursor:
        for i, row in enumerate(cursor, 0):
            if (i % increment) == 0:
                arcpy.SetProgressorPosition(i)
            fieldValue = row[0]

    arcpy.SetProgressorPosition(i)
    arcpy.AddMessage("Method 2")
    arcpy.AddMessage("\tIncrement = {0}".format(increment))
    arcpy.AddMessage("\tElapsed time: {0}\n".format(time.clock() - beginTime))

    # Method 3: use increment of 1
    # ===================================
    increment = 1
    arcpy.SetProgressor("step",
                        "Incrementing by 1 on {0}".format(inTable),
                        0, record_count, increment)

    beginTime = time.clock()
    with arcpy.da.SearchCursor(inTable, [inField]) as cursor:
        for row in cursor:
            arcpy.SetProgressorPosition()
            fieldValue = row[0]

    arcpy.SetProgressorPosition(record_count)
    arcpy.ResetProgressor()
    arcpy.AddMessage("Method 3")
    arcpy.AddMessage("\tIncrement = {0}".format(increment))
    arcpy.AddMessage("\tElapsed time: {0}\n".format(time.clock() - beginTime))

    arcpy.AddMessage("Pausing for a moment to allow viewing...")
    time.sleep(2.0)  # Allow viewing of the finished progressor

except Exception as e:
    arcpy.AddError(e[0])

Thèmes connexes

9/12/2013