LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

QMH Template - UI Confusion

Solved!
Go to solution

Hi, relative beginner here. I’ve inherited a project using the Queued Message Handler that needs some work and it also looks like a goof fit for a future project I have in mind. I’m getting confused in how the UI is set up using a typedef consisting of both controls and control refnums, but the event handler in the block diagram is interacting with a separate set of controls built on the front panel.

typedef.png

 

The above control does not appear on the front panel of Main.vi. I take it the control has been deliberately hidden (unattractive as it is)?

Main.vi has its own set of controls with the same names that I presume were placed separately. Let’s call these the interactive controls to (hopefully) make things clear.

frontpanel.png

 

The Initialize case in the message handler then connects references to the interactive controls with the refnums in UI Data.ctl using a Bundle by Name function. Does this just initialise the values in the refnums once, or does it make a permanent connection between the interactive controls and refnums that have come from UI Data.ctl?

blockdiagram.png

 

Last, but not least, when I go to edit the events handled by a case in the event handler, none of the controls from the typedef appear to be selectable events. Why is this?

events1.png

 

For reference, when I create a typedef from scratch (UI_buttons.ctl in this case) and pull it into Main.vi, all of the controls in the typedef appear as selectable event sources.

 

events2.png

 

This seems like a hell of a confusing approach to adopt in a QMH tutorial template. I have a feeling I’m missing something obvious but would appreciate any light anyone can shed on this. I’m sure I can find workarounds to get my own project off the ground and be able to pass data from the relevant controls to sub-Vis (why not use standard controls only in the typedef, then add references in Main.vi for instance?), but I assume it has been done the QMH template way for a reason and would like to understand it.

0 Kudos
Message 1 of 9
(2,089 Views)

An event structure can only register events of front panel controls and indicators (and user events) in the same VI (basically). Your Type def is neither. In your 'fresh' example they are front panel items.

In general i'd recommend _from_ wiring control refs and using those, but as an example if works as a way of showing how you can do.

G# - Award winning reference based OOP for LV, for free! - Qestit VIPM GitHub

Qestit Systems
Certified-LabVIEW-Developer
0 Kudos
Message 2 of 9
(2,051 Views)

Answering your first Question, a Type Definition (or TypeDef) is a way of giving a name to a particular Data Structure, in this case, a Cluster (similar in concept to a Struct in C, or a Record in Pascal) that contains three Controls and a bunch of References.

 

If you look in the Picture of the QMH, you can see a Pink Box to the left of the main Loop that has a pink (Cluster color) wire held in a Shift Register, and labeled "Data" -- if you right-clicked that Pink Box and chose Visible Items, you should show its Label, which is probably "UI Data", as it is an instance of this TypeDef (notice the upper-left corner of that icon is colored black, which indicates it is associated with a TypeDef).

 

As you can see inside the Message Loop, a Bundle by Name operation (which you conveniently drew a red circle around) is being used to initialize the values of these Data in the Initialize step of the QMH.  Other States might use, or change, some subsets of these Data, depending on what you want to do.

 

Bob Schor

Message 3 of 9
(2,025 Views)

"In general i'd recommend _from_ wiring control refs and using those, but as an example if works as a way of showing how you can do."

 

Thanks for the reply. Would you mind clarifying the above sentence - are you saying you generally avoid control refs? Is there a use case where the QMH template method is preferred? Cheers!

0 Kudos
Message 4 of 9
(1,998 Views)

Control references should only be used when interacting with the UI itself. If you are calling subVIs to perform functional operations you should pass actual data to those subVIs, not references to UI elements that just happen to contain the data. When developing your application make the operational modules be UI agnostic. That way they can be reused easily. Once they are tied to a UI it makes it much harder for you to reuse that code. For instance, one application uses a UI and is an interactive application with a user. Now you want to deploy a headless application that will run in a fully automated manner. If your functional code is tied to control references in order for your headless application to work they will require a UI since you are using control references. To make this work you have to dummy up some type of mock UI which a user will never interact with simply to use  the functional code. If passing actual data to the subVIs they can be easily reused as is without having to mock up a UI which would contain those control references.



Mark Yedinak
Certified LabVIEW Architect
LabVIEW Champion

"Does anyone know where the love of God goes when the waves turn the minutes to hours?"
Wreck of the Edmund Fitzgerald - Gordon Lightfoot
Message 5 of 9
(1,995 Views)

Thanks all for the advice, very useful.

 

I think I was in the right ballpark initially but this has helped clarify my thoughts. From what I understand they are creating refnums with no actual references in them, then creating front panel controls and pushing the references to those controls in there in the "Initialise" case so they can be accessed and interacted with later via the UI Data cluster.

 

Instinctively, this feels like a backwards way of doing things and creates an extra step for the programmer before they can make use of the UI Data typedef, but I can see how it opens up some possibilities for fancy, if hard to follow, UI interactions.

0 Kudos
Message 6 of 9
(1,985 Views)

@db_bh wrote:

Thanks all for the advice, very useful.

 

I think I was in the right ballpark initially but this has helped clarify my thoughts. From what I understand they are creating refnums with no actual references in them, then creating front panel controls and pushing the references to those controls in there in the "Initialise" case so they can be accessed and interacted with later via the UI Data cluster.it opens up some possibilities for fancy, if hard to follow, UI interactions.


Not quite.  Refnums (or "references") are pointers to actual Controls and Indicators on the Front Panel.  The "usual" way to create a Refnum is to find the Control or Indicator on the Block Diagram, right-click it, and "Create", "Reference".  Now, whenever you use this Reference and look at its Value, you will see whatever is present in the referenced Controls and Indicators.

 

What the Initialize step is doing is making certain that the initial values of all of the items "referenced" by the RefNum have user-specified values when the code starts to run.  It is a Very Good Idea to do this (think about it)!

 

Bob Schor

0 Kudos
Message 7 of 9
(1,975 Views)
Solution
Accepted by db_bh

@Bob_Schor wrote:

@db_bh wrote:

Thanks all for the advice, very useful.

 

I think I was in the right ballpark initially but this has helped clarify my thoughts. From what I understand they are creating refnums with no actual references in them, then creating front panel controls and pushing the references to those controls in there in the "Initialise" case so they can be accessed and interacted with later via the UI Data cluster.it opens up some possibilities for fancy, if hard to follow, UI interactions.


Not quite.  Refnums (or "references") are pointers to actual Controls and Indicators on the Front Panel.  The "usual" way to create a Refnum is to find the Control or Indicator on the Block Diagram, right-click it, and "Create", "Reference".  Now, whenever you use this Reference and look at its Value, you will see whatever is present in the referenced Controls and Indicators.

 

What the Initialize step is doing is making certain that the initial values of all of the items "referenced" by the RefNum have user-specified values when the code starts to run.  It is a Very Good Idea to do this (think about it)!

 

Bob Schor


Not  quite. The initialize step is initializing the refnums controls with the reference to the specific controls on the front panel. This cluster can then be passed to a subVI which could read/write the value of the actual control on the UI. The initialize step is not setting the initial value of any of those controls. You are correct it is always a good practice to programmatically set them to known safe and reasonable default values.

 

What I was discussing earlier was that I would discussing earlier was that I would never pass this cluster (UI Data) to any subVI that was implementing functional code. Meaning any subVI that was doing actual work, calculations, instrument control or application logic. Those types of VIs should get actual data clusters, not reference to UI elements. I would pass this cluster to subVIs that were performing UI related actions such as updating values or validating user input or similiar UI related activities. subVIs implementing application functionality and logic should not have any linkage to a UI control or indicator. This is decoupling program logic from the user interface.



Mark Yedinak
Certified LabVIEW Architect
LabVIEW Champion

"Does anyone know where the love of God goes when the waves turn the minutes to hours?"
Wreck of the Edmund Fitzgerald - Gordon Lightfoot
Message 8 of 9
(1,968 Views)

@Mark_Yedinak wrote:

@Bob_Schor wrote:

@db_bh wrote:

Thanks all for the advice, very useful.

 

I think I was in the right ballpark initially but this has helped clarify my thoughts. From what I understand they are creating refnums with no actual references in them, then creating front panel controls and pushing the references to those controls in there in the "Initialise" case so they can be accessed and interacted with later via the UI Data cluster.it opens up some possibilities for fancy, if hard to follow, UI interactions.


Not quite.  Refnums (or "references") are pointers to actual Controls and Indicators on the Front Panel.  The "usual" way to create a Refnum is to find the Control or Indicator on the Block Diagram, right-click it, and "Create", "Reference".  Now, whenever you use this Reference and look at its Value, you will see whatever is present in the referenced Controls and Indicators.

 

What the Initialize step is doing is making certain that the initial values of all of the items "referenced" by the RefNum have user-specified values when the code starts to run.  It is a Very Good Idea to do this (think about it)!

 

Bob Schor


Not  quite. The initialize step is initializing the refnums controls with the reference to the specific controls on the front panel. This cluster can then be passed to a subVI which could read/write the value of the actual control on the UI. The initialize step is not setting the initial value of any of those controls. You are correct it is always a good practice to programmatically set them to known safe and reasonable default values.

 

What I was discussing earlier was that I would discussing earlier was that I would never pass this cluster (UI Data) to any subVI that was implementing functional code. Meaning any subVI that was doing actual work, calculations, instrument control or application logic. Those types of VIs should get actual data clusters, not reference to UI elements. I would pass this cluster to subVIs that were performing UI related actions such as updating values or validating user input or similiar UI related activities. subVIs implementing application functionality and logic should not have any linkage to a UI control or indicator. This is decoupling program logic from the user interface.


So you mean something like a path control reference yields path data, and the path data then goes into a subVI that does something with it.  I agree.

Bill
CLD
(Mid-Level minion.)
My support system ensures that I don't look totally incompetent.
Proud to say that I've progressed beyond knowing just enough to be dangerous. I now know enough to know that I have no clue about anything at all.
Humble author of the CLAD Nugget.
0 Kudos
Message 9 of 9
(1,942 Views)