Text Box Display During Processing

I have a button that starts a script that takes 8-10 seconds to complete. I have a text box on the window that is bound to a string tag. I make it visible when the button is pressed and set the string tag to status messages that I want the user to see. The problem is nothing displays until a final completion message displays via system.gui.messageBox. I added this messageBox directly after changing the string tag and the text box display correctly after the messageBox displays. This was just a test as it is clearly too cumbersome and time consuming for the user to click ok after each message.

Is there a way to display the text box value each time it changes? A long time ago I ran into this problem with a Microsoft Access screen and the DoEvents function caused the system to display any screen changes every time I called the function. Is there a similar command in Ignition? I tried event.source.repaint() on the property change of this text box, but it did not help.

Look into system.util.invokeAsynchronous and system.util.invokeLater.

Something like this:

def doAsync():
     def doLater():
          //do whatever you need to do when the function is over
     doYourLongFunctionHere()
     system.util.invokeLater(doLater)
//do whatever you need to do before the function starts, like show the text box
system.util.invokeAsynchronous(doAsync)

Inside your doYourLongFunctionHere() function, you can also use system.util.invokeLater() and pass it a function that updates your text box. Make sure when you pass these functions, you leave off the parenthesis. Hope this makes sense :slight_smile:

2 Likes

Just to make sure it’s clear: Java Swing is single-threaded even on a multi-core machine, and all GUI operations must happen on that one thread. To keep the GUI from stalling, event routines must always return quickly, 0.1 second or so. Longer tasks can be put on a background thread with invokeAsynchronous – these can run as long as needed. Background tasks can pass operations and data back to the GUI thread with invokeLater. After you read the docs, you might find the later.py script module helpful.

1 Like

Thank you, both answers confirm what I was thinking. I can make this work using async logic (actually have 48 other threads running on this project asynchronously in the background to process scale data). But in this case, I really don’t want the user to have control until the button script is complete. So a button script running in the interface thread is exactly what I want, I just wanted to send progress messages during the processing. I was optimistic that Ignition would have a way to do the screen processing since it displays the text box when I call the system.gui.messageBox from the button script. I was hoping for something like system.gui.refreshScreen or system.gui.refreshTextBox. The text box I use for the message is bound to a memory tag that is updated in the processing script. After the tag update, I was hoping to just issue a command to make it display. Seems like this would be possible since system.gui.messageBox does it, but I guess not. Thanks for your help.

You might find this thread helpful, particularly the use of the glass pane.

1 Like