10-08-2008 09:48 PM
I am working on a VI that may have as many as 1000 controls (yes, it really does need that many). In order to reduce UI clutter and increase code modularity, I have partitioned the design into many sub-panels that are loaded into tabs.
Sub-panels are loaded by:
"Open VI Reference" --> "Invoke Method:Run VI" --> "Invoke Method:Insert VI"
(sorry, I don't know how to embed images here, yet)
The top level has a few of its own controls in addition to the sub-panel instances, and it will be built on the producer-consumer design pattern. The consumer loop handles interaction with the (write-only ) hardware. Each sub-panel will also have its own event loop to handle some UI coordination within the sub-panel, and also some pre-processing of the data that results from user activity within the sub-panel.
Here's the problem: From within the sub-panel, how do I pass an event up to the top-level event loop so that the hardware access request can be entered into the consumer queue?
At first it seems there are two ways I might solve this:
1) rather than using an Invoke node to insert the sub-panel, is there some way to link the front panel sub-panel frame to a VI that is instantiated in the block diagram? If there is, then I can simply use dataflow to bring the sub-panel events up to the top-level. But right now it seems there is no way to have a sub-panel except by using the Invoke node.
2) There is another way we found, but it is an ugly hack. Using the VI reference from "Open VI Reference" I can use "Invoke Method:Control Value:Get". This gives me the value of a control in the sub-panel, but there is no event signalling, so I have to resort to polling, which slows down the user interface and breaks the "Event Loop" pattern.
Are there any other ideas for how to get events from the sub-panel handled at the top level?
(of course, it is not *all* events we need to handle. The sub-panel will actually be doing some pre-processing and then send only selected user-defined events up to the top-level)
Thanks and Best Regards,
J.
Solved! Go to Solution.
10-08-2008 09:58 PM
10-08-2008 10:03 PM
Hi, Raven's Fan,
Thanks for your suggestion.
Unfortunately, I find at present no way to pass the queue reference down into the sub-vi. This is because in order to have a sub-panel, I cannot instantiate the sub-vi in the block diagram. Instead, I have to use the invoke node to load the sub-vi and connect it to the sub-panel in the front panel. At least, that is my current understanding. Is there some way to pass a reference down to a sub-panel? (Note that it is not just an instantiated sub-vi, but a sub-panel).
Thank you and Best Regards,
J.
10-08-2008 10:13 PM
I haven't used the subpanel method before, so I can't back up what I am thinking with actual experience.
But,
If the subVI that is being placed into a subpanel has a front panel control for a queue reference, I think you would be able to do the Invoke node to set the queue reference control before invoking the running of the VI.
The other idea would be not to have a queue reference control to pass in. But use named queues and let the subVI in the subpanel create its own queue reference based on the same name that was created in the main VI. When it ends, it could destroy its single queue reference, and do not force a destroy all and the queue reference in the main VI would still be a valid functioning queue waiting for another subVI in the subpanel to generate its reference to the same queue and pass data in.
10-08-2008 10:27 PM
Raven's Fan wrote:
> let the subVI in the subpanel create its own queue reference based on
> the same name that was created in the main VI.
Ok, this looks very interesting. So, named queues are global?
I'll play around with this a bit and see what happens. It would
be a very clean solution if it works.
Thank you and Best Regards,
J.
10-08-2008 10:56 PM
It worked! It's such a simple solution that I'm afraid I'm missing something....
If anyone's interested, a test case is attached.
10-09-2008 04:06 AM - edited 10-09-2008 04:07 AM
You're not missing anything. Sometimes solutions can be that simple.
You could also use User Event to pass data between VI's. The pro is that it uses no polling at all, which is possible with the queue, but than you would have to use a second loop to enable the frst loop to handle the UI.
Two other solutions to passing data to a VI that is started using the invoke node.
1. Set Control Value method to set data in a control of the VI to be started and then use method run.
2. Create a functional global (normal global and shared variable are also possible) to store data and it is available to all VI's including the dynamiccally started.
10-09-2008 06:01 AM
Hi J,
I'm very interested in your solution. But I only have lv 8.5. Could you save your code as 8.5 and upload it again? Thank you so much.
Best wishes,
Bo
10-09-2008 12:03 PM
Here are the files again, saved for version 8.0.
Also the test case has grown some since it was previously posted:
- added second sub-panel to show that both can independently
write to the top-level queue
- added a notifier to broadcast a message from the top-level
down to all of the sub-panels
Hope this helps.
Best Regards,
J.
10-09-2008 03:41 PM
Hi J.
Thank you for posting the code. They are really helpful to me.
Regards,
Bo