LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

The most elegant way to open a modal dialog from an event loop

Hi, I would like to know the most elegant (ie simple) way to open a vi configured as modal dialog from a main vi's event loop, while keeping the event loop running.

I want to open a simple text entry dialog when a button is clicked on a main vi. The main vi should keep running. The dialog should remain on top, and close (or at least be hidden) when a dialog button is clicked.

It seems this should be straightforward, but appears to be uncessarily complicated. Am I missing something obvious?

Ian
0 Kudos
Message 1 of 16
(4,244 Views)
I understand you have a timeout in your event loop or that you're firing events programmaticaly, otherwise I don't think there's any point to what you're asking. From your description it sounds like you have one loop. A better design would be to seperate the UI loop from the execution code.
If you want to keep this design and to keep the loop running, you have to open the subVI elsewhere. Run another loop which waits for a flag and opens your subVI when the flag is set. Set the flag from your first loop.
And by the way, unfortunatly simple and elegant don't always go together.

___________________
Try to take over the world!
0 Kudos
Message 2 of 16
(4,233 Views)
Well, yes the application is (a lot) more complex than I described (~100 vis), I was just trying to pair it down to the simplest example. The vi containing the event loop also runs a number of other loops, all involved with updating the front panel. The event loop handles user interaction with the vi and does have a timeout - its used to blink a few leds and to check for a clean shutdown.

I'm just adding a facility to enter some text via a 'popup' dialog in response to a button click. Having tried a few ideas, including opening a vi elsewhere, it just seems more complex than it should be.

As for elegance and simplicity, its true what you say, but I'd say the correlation between them tends to be pretty high (at least in engineering fields).

🙂 Ian
0 Kudos
Message 3 of 16
(4,217 Views)
I'm not sure if it'll work in your case, but you could try using the Run VI method and set Wait until Done to F.
Or you can have the textbox in your VI and show/hide it.

___________________
Try to take over the world!
0 Kudos
Message 4 of 16
(4,210 Views)
Hello,

I just recently tried different ways to implement the functionality you are desiring. Here is my take on this.

1. If you want to open a Couple of Vi's such that they are running and also your main vi is running in the back ground. You can dynamically call this vi and run this using Vi Server methods. That is easy and very direct. The drawback is when you build your app, You must address path issues and include these Vis separately. Another drawback is if you use remote panels and your application is web enabled, the dynamically called Vis are useless as they will not open in the browser.

2. A second method is to have two concurrent while loops. One while loop has your dialog based Vi. The while loop checks for the flag as previous reply indicated and then opens your Vi. The drawback is if you have many Vis that have to open in this fashion, you need many flags and/or parsing mechanism to decode which Vi to execute. The other drawback is this continuous polling for the flag.

3. The third Method is to Use Notifier. My event Structure when decides to open the Dialog based Vi, sends a text Notifier. The other while Loop has a Wait for Notifier and just sits there. When Notifier is received due to event activity, The Notifier retrieves the notifier and based on this notifier executes the Vi. The Vi can be made modal, or floating, or neither. Since the event structure only has to send notifier, It keeps running and My Dialog Vi runs on top of it.

I used the third method, as I can open many Vi's this way and I don't have to Poll or Parse I just send a text notifier and execute case structure with the retrieved notifier.


Just my thoughts.
Good Luck!

Mache
Message 5 of 16
(4,194 Views)
Hi,

Thanks for your list of possibilities - I agree #3 best fits my criteria best too.

Ian
0 Kudos
Message 6 of 16
(4,185 Views)
You may also want to consider queue driven task handlers. You can make as many as you want and they consume no CPU time waiting for input. Do the following. Create a standard loop for your event handler. Create another loop which contains a Dequeue Element primitive with an infinite timeout. When your dialog event fires, send an element to the queue. This will start the loop and launch your dialog (which does not have to be dynamically called). You can have as many task handler loops as you want, all started by different queues, fired from the event structure. Remember to fire a queue event in your cleanup code to stop the loops when you exit, otherwise your program will hang. I like to make the queue type a strict typedef enum and feed this enum into a case structure in the loop. That way I can send info with the queue element, such as launch dialog or stop.

I have attached an NI-Week presentation I made which gives a variant of this (queue and event structure are in the same loop - queue now has zero timeout). You are usually better off putting the queue and event structure in the same loop to avoid race conditions. But, in your case, you need separate loops.
Message 7 of 16
(4,177 Views)
I need to work up a set of examples for different styles of doing this one of these days... Everytime I see this discussed, it appears, to me, that everyone misses the obvious solution and always calls for parallel loops. I have many dialogs in my programs and I practically never need another loop.

A dialog does not need to have an internal loop inside. Just call the VI with an init case to pop the front panel using VI server property and then when finished have the OK button (or whatever) close the front panel. This VI is in the main loop dataflow path and doesn't block the main program.

I've attached an example where you can tweak a main loop variable from a dialog.

There are many styles that can be accomplished with this scheme.

Randy
0 Kudos
Message 8 of 16
(4,009 Views)
I should add, if your main loop stops while waiting on an event, then my example isn't very appropriate. However, usually my programs are looping doing DAQ or something, so it all works nicely.
0 Kudos
Message 9 of 16
(3,997 Views)
Second attempt to reply:

Thanks, extremely interesting. I think your technique is very neat (read elegant) and although as you say, not precisely appropriate to my requirement it can easily be modified to suit. This is exactly the sort of thing I was looking for.

It must have occurred to you, as it has to me, that you could use user-events instead of the queue, so I tried it out. My modified version of one of your examples is attached.
0 Kudos
Message 10 of 16
(4,134 Views)