LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Looking for an elegant way to manipulate main VI from Sub VI

Currently the best way I can think of is to put a referance to every item on my front panel within a functional global. Every sub-VI then has programatic access to the front panel (using property nodes) and can manupulate it as things change. My problem is that this is not elegant. I devote half of my main program to placing the wires to move the objects into the functional global (57 wires into an array to be exact). If I want to add button on the front panel, I then have to break my code to add a new varaible. I was wondering what creative ways people handle this very style oriented question.
 
Is there a way to get a referance to the members on the front panel of the main VI from inside the sub VI just using a referance to the application? the VI?
 
Thanks -
Kevan
- A frustrated application builder
0 Kudos
Message 1 of 14
(7,234 Views)
Hi "Kevan
- A frustrated application builder"
 
I can relate. I had an app with about 211 controls/indicators that I needed to manipulate to present an arbitrary access system that supported backing out the way they came in an logged as it went.
 
"Back in the day..." of LV 5.1 there was no such thing as control references. All o fthe GUI work had to be done IN THE GUI. I thank God he let NI invent control references!
 
Ideas
 
1) Use named access to your controls and indicators. You could force a naming convention that dicated the data type as part of the label or similarly include the data type in the objects help text.
 
2) Use a "mimi-state-machine" in your start up state that populates all of the control references for a type-def'd cluster.
 
3) Skip the data type concerns mentioned in #1 above and just do a trial and error type-cast of the control reference to more specific types. No error indicates you found the corrrect class.
 
4) Only pass the req'd control references to sub-VI's that affect the GUI.
 
5) Similar to #4 but all sub-VI's that affect GUI can become action engines that get initialized with the control ref nums that they affect.
 
 
I would be interested in hear how others have approached this question!
 
Ben
Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
Message 2 of 14
(7,227 Views)
Hey guys,
 
I've used the following method to manage UI manipulation for my apps over the past 4 years, and have found it to be quite scalable.  I have a typedef cluster containing a reference to every control on my panel that needs manipulating.  I use a Bundle By Name during initialization of my main VI to bundle all the control references of my UI controls into this cluster (I use a hidden dummy control of my typedef wired to the middle terminal of the Bundle By Name).  I then wire that cluster to the border of my main event handling loop for my VI.  Now, whenever I have a case that needs to manipulate the UI, I can use the cluster wire and unbundle just the control references I need.  Furthermore, since it's a typedef, if I need to manipulate my UI from within a subVI, I simply wire this cluster into the subVI and unbundle the control references I need from within the subVI.  Whenever I add new UI elements, I simply add new items to my typedef and bundle those control references into the cluster during initialization.  There is no code breakage since all the typedef instances update with the new control information.
 
Hopefully that explanation made sense...let me know if not, and I can add some screenshots to try to make it more clear.  Note that I don't need any functional globals, the cluster gets created during the main app initialization, and the wire gets passed directly into any subVI that needs it.
 
-D
Message 3 of 14
(7,219 Views)

Hi,

I had also similarly group indicator references into cluster. I did try to avoid using too many indicator by using for example list boxes when amount of data is huge. else you could also group similar data into array first before grouping them together with cluster. By using a event structure in the main VI, you can control when and where things happen.

Hope that helps.

Goy

Message 4 of 14
(7,194 Views)
This depends on what you want to do with the VI.  I find an elegant method of passing all references of controls to a subvi for manipulation is to just pass the reference to the "parent"vi.  With this reference you can use a pannel property node and then a Controls[] nods no you have a reference to all controls (works for all objects, decorations...) in a convenient array.  Pass this array to a loop with self indexing, get either the class name class id or even the label name (name of the individual controls) and handle them in a case structure.  This is the most elegant and manageable method of accomplishing GUI manipulation on large numbers of controls.  instead of a case structure you can make a polymorphic GUI handler (will handle by type) or use a plug-in architecture where the handler is called dynamically (this is harder to implement but easier to extend than the case structure)  Hope this helps-
Paul
Paul Falkenstein
Coleman Technologies Inc.
CLA, CPI, AIA-Vision
Labview 4.0- 2013, RT, Vision, FPGA
Message 5 of 14
(7,184 Views)

Thanks so much for your tips.

I think i figured out some interesting solutions that dont involve using lots of wires and creating lots of clutter.

I decided to Functional Global the referance to the Main VI.  From that I can change the values with the invoke node. If I need to actually get a referance to a front panel object, I am using the Main VI referance, some property nodes, and the name of the Object (Label) to get a referance to that object. I am in the process of re-working the code I broke to switch to this method - but learning this now will save me hours (days) later when I have to write my next app.

Thanks again,

Kevan -

0 Kudos
Message 6 of 14
(7,156 Views)

Hi Kevan,

The method you plan on employing will save on diagram space, but as your UI expands, the code you have that will be iterating through the panel objects trying to do label matching in order to get/set properties will become slower and slower.  The only "clutter" in the method I described is the large Bundle By Name that takes place during initialization of my main UI, and that code is off to the far left in my main UI diagram and doesn't get in the way.  Also, the method you describe is rather fragile in that, if you decide to rename any front panel controls, you'll always have to search your diagrams for places where you reference that control via its label so your VIs won't break.

I've always found reference passing via a typedef cluster to be the most robust way to handle UI manipulation in my main app diagram and in subVIs.  It requires a little more work up front to construct the control reference typedef cluster, but I guarantee it's faster in the long run, both for program execution and maintenance time.

-D

 

Message 7 of 14
(7,151 Views)
I would like to second Darren's recommendation.  I have been using this method since LV6.0 (when references became available) and it works really well.  The first thing I do after I lay out the front panel of any GUI is create a typedef cluster of the control references.  It really makes your life much easier.
Message 8 of 14
(7,127 Views)

Hi Darren

I read about your approach and wanted to try it out.  Can you please provide a small sample program of how you add control references to the cluster.  I was having problems in creating the cluster without actually placing the control inside it.

Thanks

Zulfi

0 Kudos
Message 9 of 14
(7,017 Views)

Hi Zulfi,

Here's what you do.  Create a strict typedef cluster.  Drop control references into it.  Change the type and label of those control references to match the control references you will be wiring in on your main VI diagram.  Save the typedef.  Now in your main VI, in the initialization section of your code (which should be the far left of your diagram), drop a Bundle By Name function.  Now drop a dummy copy of the strict typedef cluster on your panel and hide it.  Wire this control terminal to the middle terminal of your Bundle By Name.  Now wire the control references into each input of the Bundle By Name.  Now the output cluster wire of the Bundle By Name contains all your control references.  You can then use this wire anywhere on your diagram to unbundle control references when you need them with the Unbundle By Name function.  If you want to do this in a subVI, just create an input on the subVI that is the strict typedef cluster, wire in the afore-mentioned wire to this terminal, and use the Unbundle By Name function inside the subVI to get whatever references you need. 

Hope this helps,
-D
0 Kudos
Message 10 of 14
(6,990 Views)