Preventing multiple clicks with a button

I have a button with some scripts behind it, it takes about 3 seconds to complete. During the script execution the screen renders useless but i found that if I click the button 2 times during the script execution, it will execute those 2 times.

I want to prevent the button from being clicked multiple times to prevent it from running a bunch of times. I planned on using a tag and enable/disable the button based on the script.

Does anyone have any other suggestions or recommendations? Thanks

Andrew

I recommend making the script run asynchronously because if the script is freezing the UI thread then you might have problems with disabling/enabling the button.

If you put the script in an asynchronous function call then you can disable the button before running the script and re-enable the button when the script is done running. It’s a confusing pattern when you first look at it but it is extremely useful for database interaction and heavy duty scripting.

Psuedo code: (With [numbers] added to show the order in which things happen)


# Disable button until script is done running
[1] myButton = event.source 
[2] myButton.enabled = False
[3] myVariable = "About to start a long running script."

# Run the script in function called asynchronously so UI will still be responsive
# Also pass in any data that your script will need
# The script in these functions will not execute until called below by invokeAsynchronous
[5] def runTheScript(event=event, myVariable=myVariable):
    [6]import system
    # Run the script here
    # Don't do anything UI related here. If you need values from components
    # get them before calling this function and pass the values into the function
    # variables available within the scope of this function are also available
    # to the updateUI() function
     [7]myVariable = "%s  And now the script has been run." % myVariable
    
    # Function to call after script is finished, defined within the runTheScript() function 
    [9] def updateUI():
          # myButton was not passsed in so redefine it here
          # event was passed in so it is accessible
          [10] myButton = event.source
          [11] myButton.enabled = True
          # If script produced results to be displayed then update the UI here
          [12] event.source.parent.getComponent("myTextBox").text = myVariable

     # After script has run call the updateUI function
     [8] system.util.invokeLater(updateUI)

# Start the whole thing with invokeAsynchronous
[4] system.util.invokeAsynchronous(runTheScript)
1 Like

Thanks, I am actually trying out the invokeLater function, it was recommended for interacting with the GUI.

I’ll let you know what i decide on, thanks.

8 years have passed :slight_smile:
which way did you go?

I used invokeLater and it works great

1 Like