If I bind button with an action to update its text or even another label during execution, it only updates at the end of execution not during execution.
Eg if I have a button and bind the following to the actionperfromed event it does not behave as expected.
Technically, we should be moving the setting of text back into the EDT to prevent thread locks. It gets messier, but should look something like this.
In app.gui, place the following method
def setText():
evt.source.text = text
In you button actionPerformed script, place the following
def doLater(event=event):
#Initialize global variables to pass into back to edt
global evt
evt = event
global text
text = ""
#import stuff
import time,system
from app.gui import setText
text="Waiting 2 seconds"
system.util.invokeLater(setText)
time.sleep(2)
text="Waiting 5 seconds"
system.util.invokeLater(setText)
time.sleep(5)
text="Finished"
system.util.invokeLater(setText)
system.util.invokeAsynchronous(doLater)
I like Kyle’s approach but I implemented it in a different style below.
Kyle’s script is written like he’s using Python 2.1, where nested scopes are disabled by default. Heh, most people that have been scripting in Ignition for awhile are probably writing Python 2.1 code.
In Ignition 7.4.0 Python was upgraded to Python 2.5 which allows nested scoping by default. This means that Python functions, classes and methods can access variables in outer scopes without having to do anything special. This can simplify and make code nicer.
Here’s a rewrite of Kyle’s script using nested scoping. Put this script in the actionPerformed event script of the button. In this style there is no need for global variables or a function in app.gui.
Caveat: In Ignition nested scoping doesn’t work in top level Python functions in the Script Module Editor and in event scripts but the IA developers plan to fix this in Ignition 7.7. So for example the doLater function above could not access variables outside its scope because it is a top level function.