LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

UI-Triggered Event vs. Value (Signaling) Event?

Solved!
Go to solution

Is there any way from within the event structure (e.g. event data node) for me to discriminate whether that event handler was fired by a direct UI interaction (e.g. change of control value, typing in a string field, click of boolean button, etc.) versus a programmatic execution of the "Value (Signaling)" property node?  It would be very handy to be able to use logic in the event handler to act differently depending on the source.  I see a "Source" enum available in the event data node, but this seems to be "LabVIEW UI" no matter what, and never changes when I call this handler programmatically with write to a Val(Sgnl) node.  Thanks! 

0 Kudos
Message 1 of 12
(258 Views)

If you're using a Value (Signaling) node, you should be doing it with the express idea that the two events are equivalent, since that's the exact purpose of that node.

 

If you want to do something different on a programmatic change, just use a "user event", with the data of the user event being the new value, and then have the case that runs the user event write that value to the control as well as whatever else the event needs to do.

Message 2 of 12
(229 Views)

Thanks @kyle97330... I'm aware of the user event approach, but it just gets messier with the extra create/destroy/register event blocks, a UE wire to track around, additional handler, etc.  It would be so much cleaner to have an additional enum in the "Source" data node which lets me decide in the handler if I want to do something different based on whether it was UI generated or property-node generated.  

0 Kudos
Message 3 of 12
(225 Views)

Hi Nate,

 


Nate@UT wrote:

It would be so much cleaner to have an additional enum in the "Source" data node which lets me decide in the handler if I want to do something different based on whether it was UI generated or property-node generated.  


Use a different event case for your "property-node" generated events (by using a different control).

Or use UserEvents instead! (That's what they are made for!)

Best regards,
GerdW


using LV2016/2019/2021 on Win10/11+cRIO, TestStand2016/2019
0 Kudos
Message 4 of 12
(167 Views)
Solution
Accepted by topic author Nate@UT

@GerdW wrote:


Use a different event case for your "property-node" generated events (by using a different control).


You even do not need a different event case. You can handle two events from different controls in one event case. You then can use the control reference data node to distinguish between the controls, e.g. by reading the controls label.

 


Nate@UT wrote:

It would be so much cleaner to have an additional enum in the "Source" data node which lets me decide in the handler if I want to do something different based on whether it was UI generated or property-node generated.  


Time for LabVIEW idea exchange (https://forums.ni.com/t5/LabVIEW-Idea-Exchange/idb-p/labviewideas)?

 

0 Kudos
Message 5 of 12
(156 Views)

And if you used a queued message handler architecture such as the JKI state machine or DQMH you would put the relevant code in its own state handler and trigger that from wherever you need in your VI. Yes the according event case is NOT implementing the operation but deferring it to a different explicit state that can be invoked from anywhere else too, if desired with extra parameters that can be used to determine source specific behavior.

 

Trying to determine after the fact who generated a specific event is a very common idea. But it always seemed to me like trying to put the cart before the horse. Instead start with an architecture that allows to annotate events with some parameters of some sort. Queued state machine designs are easy to do that with.

Rolf Kalbermatter
My Blog
0 Kudos
Message 6 of 12
(146 Views)

Thanks as always to the community for responses. I will file a new feature request as suggested.

 

I think the use of Val(Sgnl) property node has one major advantage over a User Event approach which boils down to this: it is type-erased!

 

I.e. I can write a variant value to a Val(Sgnl) property node which is bound to a generic control refnum and LabVIEW will still fire the Value Change event for the specific control referenced and interpret the NewVal as the correct type in that handler's Event Data Node.  (This is where I would like to know if the event arose from the Val(Sgnl) write or from a Front Panel modification.)

 

I can't figure out a way to achieve this same type erasure using User Events because I can't programmatically generate a specific UE by passing a "more generic" User Event (since that simply doesn't exist AFAIK). 

 

Without type erasure provided by variants, I would need to recreate the typed UEs as well as several underlying layers of VIs for each specific control type that I want to support with the desired functionality.  This gets to be a maintenance nightmare (possibly exponentially!)

 

My rationale for type erasure is essentially for a serialization feature (reading & writing user preferences to files)... similar to the MGI Read/Write Anything package (e.g. has variant support) but with some added bells & whistles (e.g. ability to generate an event when a preference entity is Read, so that similar behavior can be executed in the same fashion as a corresponding Front Panel control change by the user... but different enough where I would like to employ logic based on the exact event source if I knew what it was.)

 

I could probably spend a bunch more time detailing the use-case, but it's sort of tangential to the higher-level architecture and state handling.  My particular application already makes heavy use of Actor Framework, so migrating to something like a QMH, JKI state machine, or DQMH wouldn't necessarily address the type erasure limitations of the UE approach compared to the Val(Sgnl) approach.

0 Kudos
Message 7 of 12
(64 Views)

As a relatively new programmer, here’s the method I use: when an event fires, I check the NewVal of the control. If the event was triggered by a user interacting with the UI (like clicking a Boolean button or typing in a string field), the NewVal will reflect the user’s input — for example, True for a button click or the new text for a string control. If I want to fire the event programmatically, I use the Value (Signaling) property and set the control to a known default value, like False for a Boolean or an empty string for a text field. By comparing the NewVal, I can easily tell whether the event came from the user or from the code.

 

For example:

 

  • If the user clicks a Boolean button, NewVal will be True.
  • If the user types "Hello" into a string field, NewVal will be "Hello".
  • If I programmatically set the button to False (or the string to ""), the event will still fire, but I can recognize that it was triggered by code, not by the user.

 

0 Kudos
Message 8 of 12
(56 Views)

Nate@UT wrote:

I can't figure out a way to achieve this same type erasure using User Events because I can't programmatically generate a specific UE by passing a "more generic" User Event (since that simply doesn't exist AFAIK). 


I can't say that I understand what you want to do.

For me this sounds like creating an User Event with a parent class and Generating User Events with child classes?

 

 

0 Kudos
Message 9 of 12
(54 Views)

@maxnoder1995, I understand what you're suggesting, but the "programmatically set" case needs to have a meaningful value for my application -- not just a 'throw-away value' which is used only for the purposes of encoding the event source.

0 Kudos
Message 10 of 12
(45 Views)