Change the text in a label on a time delay

I have a label that has a text value of “READY TO SEND”

It changes the value to “SENT” on a button press in the same view.

How do I set a 5 second timer to change it back to “READY TO SEND”??

Edit: This is a perspective project. Sorry for the lack of detail, was writing this as I was walking out the door. I will give these a try on Monday. Thanks everyone for you input!

This approach should work if added to your button’s onActionPerformed event:

def endSequence ():
	event.source.parent.getComponent('yourLabel').text = "READY TO SEND"
system.util.invokeLater(endSequence, 5000)

Edit: Assuming this is Vision

1 Like

You’re assuming Vision.

1 Like

OP stated “view”, so I would assume Perspective. Probably best if the OP clarified.

2 Likes

Ah I didn’t see that. Invoke later doesn’t work with perspective I didn’t think :thinking: I could be wrong
Or rather, it’s unnecessary since perspective scripts don’t lock up the gui

Scope is vision

2 Likes

@nminchin: You are correct; I assumed vision. I didn’t make the connection to the word ‘view,’ so @jlandwerlen is probably correct that this is a perspective question.

1 Like

With the number of times people ask questions without specifying or implying, the label should be made mandatory. Or maybe a category should be added for which module you’re using

1 Like

Assuming this is Perspective, this approach should work if added to the end of the button’s onActionPerformed event:

import time	
time.sleep(5)
self.getSibling("yourLabel").props.text = "READY TO SEND"
1 Like

I’m always loathe to use a sleep. I don’t have a solid enough understanding why though, especially in an instance like this where it seems logical. I assume if you have many of these running in a lot of places it could cause a large number of threads to be locked. But if it’s a once off or few clients, then it should be OK. You should however plan for scaling your project if necessary.

The an alternative is to set a custom prop null default to the current time when the button is pressed and use another prop bound to now(1000) if the time is non-null value. Then using a change event script, check if the time difference is greater than 5s and then set the set time to none.

3 Likes

You could also drive the nail with a sledge hammer and use java.util.Timer and java.util.TimerTask.

A little overkill, but avoids the sleep.

Personally I like the alternative you supplied.

3 Likes

A guy in Stack overflow explain well on the disadvantage of sleep. Using scheduling python script will be much better.


source:v

Jython is substantially different from CPython, and even moreso embedded in Ignition, so those points don’t really apply.

The biggest problems with sleep() in Ignition are:

  • using it on the foreground thread in a Vision Client freezes the client User Interface completely.

  • using it in gateway tag events (on the tag) ties up a workqueue thread needed to process other tags’ events. Three such sleeps simultaneously will halt all other tags’ event processing.

  • using it in events (in a project) ties up that event’s handler, delaying processing repeat events (or other tags in a tag change event’s monitor list).

The first of these is well-known, and causes developers to use asynchronous threads to perform tasks with sleep(). But the temptation to access/manipulate a Vision Client UI from that background thread seems to be irresistable, leading to occasional complete client lockups.

2 Likes

I’ve done quite a few apps in C#, and the sleep command behaves the same way, so our superstitions are well justified, but for the sake of this thread, the sleep command launched from his button to delay a label text change in a Perspective view will not lock up anything. Due to the simplicity of implementation, this is one occasion where it makes sense to use it.

1 Like

This is a crude example, uses expression and change script.

{
  "custom": {},
  "params": {},
  "props": {},
  "root": {
    "children": [
      {
        "events": {
          "component": {
            "onActionPerformed": {
              "config": {
                "script": "\tself.getSibling(\"Label\").custom.textTime \u003d system.date.now()"
              },
              "scope": "G",
              "type": "script"
            }
          }
        },
        "meta": {
          "name": "Button"
        },
        "position": {
          "height": 34,
          "width": 80,
          "x": 133,
          "y": 140
        },
        "type": "ia.input.button"
      },
      {
        "custom": {
          "textTime": {
            "$": [
              "ts",
              192,
              1662040678099
            ],
            "$ts": 1662040678098
          }
        },
        "meta": {
          "name": "Label"
        },
        "position": {
          "height": 32,
          "width": 234,
          "x": 262,
          "y": 142
        },
        "propConfig": {
          "custom.testReset": {
            "binding": {
              "config": {
                "expression": "(secondsBetween({this.custom.textTime}, now()) \u003e\u003d 5)"
              },
              "type": "expr"
            },
            "onChange": {
              "enabled": null,
              "script": "\tif currentValue.value:\n\t\tself.props.text \u003d \u0027Text reset\u0027\n\telse:\n\t\tself.props.text \u003d \u0027Button was pushed\u0027"
            }
          }
        },
        "props": {
          "text": "Text reset"
        },
        "type": "ia.display.label"
      }
    ],
    "meta": {
      "name": "root"
    },
    "type": "ia.container.coord"
  }
}

This is true, however, I avoid it everywhere so I don't end up using it where I shouldn't.

3 Likes

One question on this to the sleep expert @pturmel - the example given is innocuous enough and with a handful of clients I’m sure there’s no real damage that will be done.

But given this is perspective and everything runs on a gateway, I would assume there’s a threshold where if too many clients were on this page with the sleep script, it could cause some problems. Is that right or would this always be ok regardless of client load? Just asking for my own edification.

Perspective uses an unbounded thread pool workqueue. So a sleeping Perspective thread is not blocking anything else. It just wastes RAM and a few extra CPU cycles of overhead.

It does make reviewing the thread status on the gateway a nightmare, and makes thread dumps exceedingly slow. But it doesn’t kill functionality abruptly like the cases I list.

7 Likes