Prompt user to adjust parameter during Python Toolbox Tool execution?

358
1
Jump to solution
01-04-2023 02:34 AM
Manu
by
Occasional Contributor

I wondered whether it is possible to prompt for user input during execution of a Python Toolbox Tool?
Currently, I am working on a tool that masks a hyper-spectral image by a NDVI threshold. The user selects an image and a threshold value. From a red- and a NIR-band, the NDVI is calculated. Based on the threshold value, a mask is created. According to this mask, pixel values for all bands of the hyper-spectral image are set to a NoData value.

The entire process takes a lot of time and the NDVI threshold might have to be adjusted. Hence, I thought about storing the mask in memory and displaying it. Subsequently, the user could be asked to inspect the mask and adjust the threshold value if needed. As soon as the user is satisfied with the mask, the tool should continue and edit the hyper-spectral image accordingly.

An alternative would be the creation of two separate tools: one tool to create a mask (which is pretty fast) and a second tool to mask the hyper-spectral image. However, I think this would be more cumbersome to potential users, since they would have to run multiple tools manually.

Is it technically possible to change some parameter in a pop-up window and then continue? (I think it would be easy to prompt for user input in the message field of the tool; however, I suspect users won't expect to be asked for input and, thus, lose a lot of time until figuring out what is going on.)

0 Kudos
1 Solution

Accepted Solutions
by Anonymous User
Not applicable

You can use a tkinter dialogue.  As an example- put the askstring method where you want it to stop and get input.

import tkinter as tk
from tkinter import simpledialog

arcpy.AddMessage('App started')

application_window = tk.Tk()

answer = simpledialog.askstring("Input", "What is the string?",
                                parent=application_window)
if answer is not None:
    arcpy.AddMessage(f"Your string is {answer}")
else:
    arcpy.AddMessage("No string entered")
    answer = 'ABCDCDC'

application_window.destroy()

sub_string = 'CDC'

pairs = {}
for i in range(len(answer)): # for 1 in 7:
    # start_index = string.index(i) #<- get index of character from string
    end_index = i + 3 #<- move the end index
    if len(answer[i:end_index]) == 3: # <- check if the length of start index and end index (+3) is more than 3.
        combo = answer[i:end_index]
        arcpy.AddMessage(combo)  # <- print it
        # added for counting the items
        pairs[combo] = pairs[combo] = 1 if not pairs.get(combo) else pairs[combo] + 1
    else:
        arcpy.AddMessage(f'end of string: {answer[i:end_index]}')

arcpy.AddMessage (pairs)
arcpy.AddMessage(f' {sub_string} count: {pairs[sub_string]}')

 

View solution in original post

0 Kudos
1 Reply
by Anonymous User
Not applicable

You can use a tkinter dialogue.  As an example- put the askstring method where you want it to stop and get input.

import tkinter as tk
from tkinter import simpledialog

arcpy.AddMessage('App started')

application_window = tk.Tk()

answer = simpledialog.askstring("Input", "What is the string?",
                                parent=application_window)
if answer is not None:
    arcpy.AddMessage(f"Your string is {answer}")
else:
    arcpy.AddMessage("No string entered")
    answer = 'ABCDCDC'

application_window.destroy()

sub_string = 'CDC'

pairs = {}
for i in range(len(answer)): # for 1 in 7:
    # start_index = string.index(i) #<- get index of character from string
    end_index = i + 3 #<- move the end index
    if len(answer[i:end_index]) == 3: # <- check if the length of start index and end index (+3) is more than 3.
        combo = answer[i:end_index]
        arcpy.AddMessage(combo)  # <- print it
        # added for counting the items
        pairs[combo] = pairs[combo] = 1 if not pairs.get(combo) else pairs[combo] + 1
    else:
        arcpy.AddMessage(f'end of string: {answer[i:end_index]}')

arcpy.AddMessage (pairs)
arcpy.AddMessage(f' {sub_string} count: {pairs[sub_string]}')

 

0 Kudos