Jump to content

Encapsulating the UI question

Recommended Posts

In general using "standard" G, I have a GUI manager FG that has all my references so my UI updates (basically anything that requires writing/reading from a property node) are encapsulated. But, if I need to write values to indicators on the front panel, I just wire directly up to them rather than having an action in my FG for something like "Update Control Value" that writes to the value property of the specific property node. In OOP, is it still kosher to do the writing to indicators on a main BD, or should even values be updated from within, say, the GUI Manager class?

Link to comment

What’s the purpose of your “GUI manager”? Personally, I tend to keep all control manipulation on the block diagram of the VI containing the control. If I want a UI separated from the rest of the program I use messaging between VIs. The messages carry information, not control references.

If the “GUI manager” is supposed to provide a loose coupling between program and UI (i.e. if you want to be able to substitute a different UI) then you need to channel all UI actions through it. But you’d also need your UI in a different VI from the main code (so you could swap it out) which would prevent you writing to control terminals or local variables. So I don’t really understand the purpose of “GUI Manager”.

Link to comment
Personally, I tend to keep all control manipulation on the block diagram of the VI containing the control. If I want a UI separated from the rest of the program I use messaging between VIs. The messages carry information, not control references.

I favor this approach, too. Within a view element (and for us a view is a composite of individual view elements, not a large monolithic VI) the code handles user events (eg., button clicks) to send messages orresponds to messages by changing state (updating data or appearance). There is (generally) no need to pass control references; although I think passing control references can be a valid approach, most often I think it is not the best option in LabVIEW. Note that we do invoke lots of common code within the view elements themselves. With this approach views are quick and easy to create, and simple.

(What is important is to keep the view decoupled from the controller, by the way.)

  • Like 2
Link to comment

Wow!!! I can't disagree more with what is said here and in Ben's post (very rare).

Where should I start?

1. Ben's solution handles only the passing of control refs that are relevant to subvis from a localized FG. There is no advantage to doing so instead of passing the direct vi ref since it neither prevents races or dead refs. Besides that, this has nothing to do with a GUI Handler if you mean Model-View-Controller since not all of the control refs are handled and it is all being done manually.

What happens if you want to change the GUI or load a sub panel?

2. drjdpowell asked the right question: what is the purpose of the GUI Manager? If you write a small project (less then 50 classes and 200 vis) which is non commercial with just a single team member then you don't need to invest in architecting a MVC with plugins loaded into subpanels. In this case I would suggest you run a recursive script that will drill down into your GUI and save all the control refs at the start of the main vi and pass the result to all the subvis. However, if you are using LVOOP and break the data flow you might turn into some race conditions.

If you need future flexibility of the GUI and logic for fast development and logic decoupling between several team members under a large commercial project out of the feasibility faze I think you need to build a plugins+UI Framework architecture and most important a Hardware Abstraction Layer if your hardware might change and MVC if your logic is constantly in R&D faze. Otherwise you will invest in a system that will turn into a spaghetti code that only its first developer could manage and even he/she won’t be able to handle a fundamental upgrade.

3. Paul_at_Lowell described a FP coupled to a control handling logic that communicated with the rest of the logic and model state by messaging. This is a good design since the important issue here is to let the logic with all its subvis/classes/projects/plugins work on the state of the model that can if you want it to synchronize with the GUI. However, I have two problems with this description: he confused the goal of the MVC by requiring a "fast GUI". If his FP acts as a model out of sync from the main model since he requires that the user could change controls ASAP he is actually breaking the MVC. Besides that, you can analyze an application as a production line (I prefer this over a data flow once we have LVOOP). If he first collects UI events, send messages to the logic that in turn updates the model and then sync it with the GUI you can see that we have a dependency of operations and it doesn't matter if he located the sync operation in a coupled BD of the GUI FP or in another vi. Besides that, he also wanted to develop the GUI fast. The more coupled code needed in vi that contains the GUI the slower he will develop it since this logic is manually configured and depending on the particular GUI. The best way to get a GUI design for a new feature is by letting the user play with a FP and to comment each functionality he/she needs, give that design to the R&D for evaluation and requirements documentation and analysis. Then the marketing and management will set the time table and which sub features will be implemented. The user will evaluate and agree.

Now, this FP vi with no BD is both your GUI and your requirements documentation. Besides adding a recursive read of all the control refs, initializing/saving state and other common reusable code there should be nothing in this vi. Moreover, as long as you keep the same control names but only change the appearance and organization of the GUI you won't have to change a single thing in the rest of your code. Even removing a control might require no changes. There will simply be a redundant section in your logic. Adding a control requires change but a very simple one that most of it can even be scripted.

Anyhow, if I understand correctly, all you want to solve is the same thing Dan07 posted and answered by Ben. In other words, you just want to be able to create a subvi without problems of endless control refs and control events (that you didn't talk about yet I think is important for you since you can't pass them into subvis).

For a small/medium project I would do the following:

1. wrap the vi inside a class.

2. copy all the FP into the class control

3. create member access vis for all the class controls.

4. pass the class into each of the vis as a DVR so they could all manipulate the data inside an in place structure.

5. only the main vi needs to handle control events from the GUI and it messages the next step into a relevant queue that the interested subvi checks.

6. inside the write member access vis of the class call a special vi that has the GUI control refs and updates the relevant control by name.

7. the result should be many vis that all get the class DVR which contains the db/state of the modele, manipulate it with no races inside an in place structure while the main vi only initializes and message out (not in) events while maybe blocking UI actions until the logic comes back to the idle state.

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...

Important Information

By using this site, you agree to our Terms of Use.