TransWikia.com

Cancel event in Python Gp tools with arcpy

Geographic Information Systems Asked by user17515 on December 29, 2020

In GP-tools written in C# (ArcObjects) we can listen for the Cancel-event and react on that. I wonder if there is anything similar in Python GP-tools applying arcpy.
I googled that issue and the only thing I found was the Cancel-method on the Result-Object (so that you can ask the state of the result of a GP-tool, i.e. if it was canceled).
I’m aware that you can cancel GP-tools running in the background in the Result Window, but this Cancel-event is catched by the system and therefore the developer or the GP-tool cannot react on that.

3 Answers

This isn't an answer, but an elaboration on the question. I've published an asynchronous gp service using the code shown below. If the user cancels, the result object returned does indicate that. However, the loop runs for the full number of seconds. I would like to break out of the loop if user has canceled.

def execute(self, parameters, messages):
    secondstosleep  = int(parameters[0].valueAsText)
    output = parameters[1].valueAsText

    if secondstosleep < 0:
        messages.addErrorMessage("{0} : less than zero.".format(secondstosleep))
        raise arcpy.ExecuteError
    messages.addMessage("starting to sleep for {0} seconds".format(secondstosleep))
    slept = 0
    for t in xrange(0,secondstosleep):
        # would like to break if user has canceled
        # check for cancel here and break
        slept = slept + 1
        time.sleep(1)
    messages.addMessage("slept for {0} seconds".format(slept))
    return

Answered by Kirk Kuykendall on December 29, 2020

The only way I can think of is the use of Progressor in Arcpy. Using the Progressor, once the user press the cancel button the loop breaks. Then you can check the resulting object to see whether it is canceled by the user. Here is a sample code:

def execute(self, parameters, messages):
    import time
    n=30
    p=1
    arcpy.SetProgressor("step",
                        "Step progressor: Counting from 0 to {0}".format(n),
                        0, n, p)
    loopTime=.3
    for i in range(n):
        if (i % p) == 0:
            ##            # would like to break if user has canceled
            arcpy.SetProgressorLabel("Iteration: {0}".format(i))
            arcpy.SetProgressorPosition(i)
            #print(i)
            time.sleep(loopTime)

    arcpy.SetProgressorLabel("Iteration: {0}".format(i + 1))
    arcpy.SetProgressorPosition(i + 1)
    return

Answered by Farid Cheraghi on December 29, 2020

If you use arcmap 10.4 and up, you can set arcpy.env.autoCancelling = False to do the clean up work yourself. Example from official website.

import arcpy
arcpy.env.autoCancelling = False

def my_function(tables, output):
    temp_tables = []
    try:
        for table in tables:
            temp_tables.append(arcpy.CopyRows_management(table, '#')[0])
            # If isCancelled is True this means that the cancel button
            # has been pressed
            if arcpy.env.isCancelled:
               raise RuntimeError('Tool has been cancelled')
            arcpy.Merge_management(tables, output)
     except RuntimeError as err:
         arcpy.AddError(err)
     finally:
        # If tool is cancelled or finishes successfully, clean up intermediate data
        if temp_tables:
            for temp_table in temp_tables:
                arcpy.Delete_management(temp_table)

Answered by logan on December 29, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP