LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Refreshing a VI inserted into a subpanel

Hi all,

 

I have am struggling to comprehend the intended design of subpanels; I think it does not match my understanding to date!

 

I wish to have tab control-like interface with various VIs being inserted into one subpanel. I want the user to select a tab, and see the relevant VI appear in the subpanel. The inserted VI can then be interacted with, and periodically refreshed so that relevant indicators can be updated depending on the user's control inputs.

 

This works great when I use class-based function calls, I can call Main.vi of the class relevant to a tab, and then insert this into the subpanel. I can dynamically switch which Main.vi is inserted by switching classes, easy!

 

But when I use a non-class based calls, when a tab relates to a function that is not part of a class, I have to go through a process of selecting a VI with a static path, opening the vi reference and using VI server calls to run it (like this and this). I want to say 'call/refresh the VI inserted into this subpanel' or 'update indicators of VI inserted into this subpanel'.

 

I can get the reference of the inserted VI from the subpanel, but the execution state is 'running' as it is inserted into a subpanel, so I cannot use the Run VI invoke node (error 1000). Invoking Remove VI on the subpanel clears the reference (no more error 1000 when invoking Run VI) but loses all memory of the front panel's state and forcibly stops interaction with drop downs (not great for a persistent UI!).

 

The work around I have implemented is to never invoke Remove VI, just keep inserting a new one when a new tab is selected. I then use a time delayed send message (inspired by Actor Framework's Time Delayed Send Message) to call the Change Tab method after a period of time to refresh the currently selected VI. 

 

Any help/comments, particularly with the bit in bold are welcome!

 

PS I have previously always inserted asynchronously running Actors or QMH-driven UIs into subpanels, and consequently the inserted VIs are running independently of the subpanel owner and can refresh themselves as required. This is my first time trying to 'in-line' the call/refresh to the VI's inserted in the subpanels and it is not as neat as I had first thought! This move is because I am working with people who are not so keen on using Actors (classes was a stretch!).

 

PPS It occurs to me that the use of classes is essentially providing the VI paths, for a Call By Reference and that is just part of the magic of dynamic dispatch behind the scenes.

CLA - Kudos is how we show our appreciation for comments that helped us!
0 Kudos
Message 1 of 5
(1,447 Views)

@MaxJoseph wrote:

But when I use a non-class based calls, when a tab relates to a function that is not part of a class, I have to go through a process of selecting a VI with a static path, opening the vi reference and using VI server calls to run it (like this and this). I want to say 'call/refresh the VI inserted into this subpanel' or 'update indicators of VI inserted into this subpanel'.


That is how people often complicate things, it's often not needed.

 

Of course, if you want an unknown number of VI instances, you need to create them dynamically.

 

But if you do know the number of instances, things can be a lot easier.

 

You can insert any panel in a subpanel. If the VI isn't reentrant, you can use a static VI reference to insert it's panel in a subpanel. Then, you can use the sub VI as a normal subVI (e.g. without a UI loop). Alternatively (or in combination) The VI can return it's control references, and you can use those to update the panel.

 

If the VI is reentrant, you can still put a known number of instances on the diagram. Each VI returns it's reference, you can put in a subpanel, and use Call By Reference to update it.

 

I always avoid dynamically loading VIs when it's not needed. Sometimes it is needed, but people seem to default to dynamic loading for some reason. I especially don't like how the dynamic VIs keep running when I stop the main. Of course, sometimes that's a nice feature.

 

I don't see how anything is different between class VIs and stand alone VIs. The mechanism is exactly the same.

 


@MaxJoseph wrote:

I can get the reference of the inserted VI from the subpanel, but the execution state is 'running' as it is inserted into a subpanel, so I cannot use the Run VI invoke node (error 1000). Invoking Remove VI on the subpanel clears the reference (no more error 1000 when invoking Run VI) but loses all memory of the front panel's state and forcibly stops interaction with drop downs (not great for a persistent UI!).


Running state has little to do with the panel being inserted in a subpanel or not.

 

You should be able to use a (static) VI reference, put the panel in a subpanel, and use Call By Reference.

 

You probably make a VI with a loop, and put it in a subpanel. Then, running it isn't possible, because it is already running. (Again this is the same for any VI, in a class or not).

 

You have to choose:

1) Make a VI that runs, and send messages to it.

2) Make a VI that doesn't run, so you can call it to update. Either by reference or not.

 

wiebeCARYA_1-1653905561643.png

EDIT: 3rd way:

wiebeCARYA_0-1653905921176.png

 

 

Message 2 of 5
(1,440 Views)

Many thanks for the insightful reply, lots to think about!

 

My understanding is that the Property of the VI Reference in each of you examples would be 'Running'. And this means that I cannot Invoke Run VI on them.

 

I can see how your examples catch the ways I have been calling the relevant VIs, particularly the second! This works fine, but it seems a little clunky to me to use the This VI Reference on the connector pane. I would like there to be a call inserted VI method, I wonder is there an underlying, computer science reason why this would be bad?

CLA - Kudos is how we show our appreciation for comments that helped us!
0 Kudos
Message 3 of 5
(1,430 Views)

Here's one way I use sub-Panels to allow me to examine selected data in two States of a State Machine:

  • I have a sub-Panel where the "Show Me" routines ("Show Me Data" and "Show Me Results") will be displayed.
  • The two "Show Me" routines have Front Panel displays (and Windows) sized to fit the sub-Panel.
  • The "Show Me" routines are coded as While Loops, "Do Until I Say Stop", with either a simple "Stop" button in the Show Me routine, itself, or a referred value from a "Stop Display" button on the Caller passed in as, say, a Global Boolean.
  • The "picture" (sorry, not even a Snippet) shows how easy it is to call and use such a sub-Panel.  The yellow Icon that looks like a "While Loop" (I cribbed the design from something AristosQueue showed me) is the Icon I use for sub-VIs that run as While Loops until terminated, with the name of "What they Do" inside.  Just before I run the sub-VI, I insert it into the subPanel using the Static VI Reference Function from the Application Control subPalette, then run the sub-VI (which which runs until I stop it using either a Stop Control inside the sub-VI, or a Control in the Caller that has a reference inside the sub-VI), after which I remove the VI from the sub-Panel (I could, I suppose, have chosen to leave it displayed ...

Sub-Panel Call.png

I hope this helps.

 

Bob Schor

Message 4 of 5
(1,384 Views)

@MaxJoseph wrote:

My understanding is that the Property of the VI Reference in each of you examples would be 'Running'. And this means that I cannot Invoke Run VI on them.


Not for the 2nd. Run VI would work.

 

Keep in mind that Run VI does need an idle root loop. So if the user activates a menu, the Run VI will wait for the menu to go way.

 


@MaxJoseph wrote:

I can see how your examples catch the ways I have been calling the relevant VIs, particularly the second! This works fine, but it seems a little clunky to me to use the This VI Reference on the connector pane. 


I'm not sure why that's clunky.

 

In general, I'd advice to make VIs put themselves in the subpanel. But I'd also always put the VI in a class. Then the VI returns it's class, with the VI reference and control references set.

 


@MaxJoseph wrote:

I would like there to be a call inserted VI method, I wonder is there an underlying, computer science reason why this would be bad?


I think that would make the subpanel more then it is.

 

And it only saves one call. You'd still need to get\set all input\outputs by reference, so why not also call by reference?

 

For you (at the moment) it makes sense to have the panel and treat it as the thing to execute. Usually, you'd have the VI reference, and don't care if the VI is in a subpanel or not.

Message 5 of 5
(1,365 Views)