控制脚本工具的进度条

AllSource 1.4    |

由于脚本工具共享应用程序,因此您可以控制进度条。 可通过选择默认进度器或步骤进度条来控制进度条的外观。

要了解有关进度条的详细信息,请参阅了解脚本工具中的进度条

下面的代码演示了默认进度条和步骤进度条的完整用法。 将此代码复制到 Python 编辑器中,将其保存,然后为其创建脚本工具。 脚本工具有两个长整型参数,如代码注释中所述。 然后运行脚本工具,同时为参数提供不同值(以 n = 10p = 1 开始,然后尝试 n = 101p = 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 = arcpy.GetParameter(0)
p = arcpy.GetParameter(1)

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

arcpy.AddMessage("Running demo with: {} by {}\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 range(1, 4):
    arcpy.SetProgressorLabel("Working on 'phase' {}".format(i))
    arcpy.AddMessage("Messages for phase {}".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 {}".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: {}".format(i))
        arcpy.SetProgressorPosition(i)
        time.sleep(loopTime)

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

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

最大值可能很大时选择一个合适的增量

编写迭代次数未知的脚本并不罕见。 例如,脚本可以使用 arcpy.da.SearchCursor 迭代表中的所有行,而您事先并不知道有多少行,也就是说您的脚本可用于迭代从几千行到数百万行的任意大小的表。 为大型表中的每一行递增一次步骤进度条是一个性能瓶颈,您可能希望避免应对这样的问题。

要演示和评估步长进度条的性能问题,请将下面的代码复制到 Python 编辑器中,然后将其保存,之后为其创建一个脚本工具。 该工具有两个输入:一个表参数和一个字段参数。 使用大小不同的表运行脚本工具,但请确保尝试包含 10,000 行或更多行的表或要素类,以查看性能差异。

该脚本执行三个单独的循环,每个循环会读取表中的所有行。 循环的不同之处在于它们更新步骤进度条的方式。 第一个和第二个循环以较大的增量更新步骤进度条,最后一个循环为每行增加一次步骤进度条。 当您运行该工具时,会看到最后一个循环需要更长的时间来运行。

您可能希望将此代码中的技术用于您的脚本工具。


'''
Demonstrates a step progressor by looping through records on a table. Use a 
table with 10,000 or so rows - smaller tables will finish too quickly to assess.
   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.management.GetCount(inTable)[0])
    if record_count == 0:
        raise ValueError("{} has no records to count".format(inTable))

    arcpy.AddMessage("Number of rows = {}\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 {} on {}".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 = {}".format(increment))
    arcpy.AddMessage("\tElapsed time: {}\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 {} on {}".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 = {}".format(increment))
    arcpy.AddMessage("\tElapsed time: {}\n".format(time.clock() - beginTime))

    # Method 3: use increment of 1
    # ============================
    increment = 1
    arcpy.SetProgressor("step",
                        "Incrementing by 1 on {}".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 = {}".format(increment))
    arcpy.AddMessage("\tElapsed time: {}\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])

相关主题