UI Interest Group Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

An Extensible, Object-Oriented Alternative to XControls

Sorry all.  I know this has been a long time coming.  Here is a link to the presentation I gave at NIWeek 2018 about QControls:

 

Extensible & Mod UIs: Extend the VI Server With Object-Oriented Techniques

 

And here is the link to the source code:

 

SpellcheckString QControl at GitLab

 

I will be presenting more about the Spellcheck algorithms used and the benchmarks of the algorithm at Americas CLA Summit 2018 next week. I'll post a link to that presentation soon.

Quentin "Q" Alldredge

Owner, Q Software Innovations, LLC (QSI) | Director, GCentral | Admin, LabVIEW Wiki
Tech Lead, Hill AFB LabVIEW Center of Excellence | Creator, The QControl Toolkit
Certified LabVIEW Architect | LabVIEW Champion | NI Alliance Partner


Message 21 of 36
(788 Views)

All,

 

Darren and I have been working to get QControls on the priority to become part of LabVIEW Core. If you feel this would be a beneficial to you, please go vote on the Ideas Exchange:

 https://forums.ni.com/t5/LabVIEW-Idea-Exchange/Add-QControls-to-LabVIEW-Core/idi-p/3908067

 

Please kudo! Thanks in advance!

Quentin "Q" Alldredge

Owner, Q Software Innovations, LLC (QSI) | Director, GCentral | Admin, LabVIEW Wiki
Tech Lead, Hill AFB LabVIEW Center of Excellence | Creator, The QControl Toolkit
Certified LabVIEW Architect | LabVIEW Champion | NI Alliance Partner


0 Kudos
Message 22 of 36
(553 Views)

I have a feature request or question.  Is there a way to get the event handler to be notified when a property has been written to the control?  One option I've thought of is to have a user event that is put into the State Data, and when a property is written, in that VI we will set the data, but we will also generate that user event.  This way the Event Handler can subscribe to that user event, and get notified when properties have been written.  Is this feature already in the QControl somewhere?  If it it might want to be added, or have a way to make a template that creates it.  Also have you thought about scripting to generate templates for the properties reading/writing?  If so you could make a template that also had this user event stuff being written.

0 Kudos
Message 23 of 36
(541 Views)

Hooovahh,

 

The user event is the way to go for what you want to do.  It does not need to be in the State Data but there is no problem putting it there.  The State Data DVR is for the data that needs to be accessible by the Properties/Methods and the Event Handler.  Instead the user event can be started in the Initialize Control method before the Call Parent Method, then add the event reference to the class private data, and then destroyed it in the Close Control method.  Register it in the Event Handler method just as you said.

 

As for making some scripting to make this easier and make creating properties easier, that is good feedback.  I'll have to work on adding some.

Quentin "Q" Alldredge

Owner, Q Software Innovations, LLC (QSI) | Director, GCentral | Admin, LabVIEW Wiki
Tech Lead, Hill AFB LabVIEW Center of Excellence | Creator, The QControl Toolkit
Certified LabVIEW Architect | LabVIEW Champion | NI Alliance Partner


0 Kudos
Message 24 of 36
(528 Views)

Sweet thanks, I made my first QControl and it is a defined slider, for selecting the start, and end date/time for selection, using non-uniformly spaced values, in a slider.  Plenty of room for improvement but it uses a state machine in the core (QMH), and the user event I mentioned earlier to trigger when a property is written.  Both of which I think adds alot of flexibility to the QControl.  I get that when you write the property you can just do the work on the control reference there, but in my Event Handler.vi I may have a state machine that does things like sets up some standard UI things, and for code reusability I'd find it better to just generate the user event stating what property was written, and then have that state machine handle it.

 

EDIT: Oh and if you haven't already, you should setup your NI profile to get a notification any time the term "QControl" is used on the forums.  I subscribe to terms like "Brian", "Hooovahh", "LAVA", and "TDMS".  Go to My Settings, Subscriptions and Notifications, Search Subscriptions, or I think this link will work.  Terms are separated by a space and don't use quotes.

0 Kudos
Message 25 of 36
(500 Views)

This looks pretty awesome, but I'm having a few issues, specifically with the DataGrid QControl. I posted a question in the Idea Exchange before I found this thread, and apparently I can't delete it there 😕

 

Anyway, I'm trying to get rolling with the DataGrid. I've got the configuration tool installed using the VIPM file. I also downloaded the DataGrid.lvclass hierarchy and have been manually adding it to a project (first question, is this the right way to install that, or is there a way to add it to the palette?)

 

In playing around with it, I have it working with just the "Create" function, but I'm getting hard LabVIEW crashes with Exception: Unknown 0x0000... at EIP 0x624FC72E, possible cause \DataGrid Configuration\DataGrid Config\Get Config.vi. It happens when I right-click the control to invoke the editor.

 

Any thoughts on why I'd be getting this, and am I actually using it correctly?

0 Kudos
Message 26 of 36
(483 Views)

I haven't created a package for the DataGrid, itself, so I don't have it in the palette.  Maybe when I add it to the main toolkit I'll get it added to the palettes too.

Usually you would have ones you create in your project so using the DataGrid in your project is acceptable.  Just to be sure, you did install the QControl Toolkit from the Tools Network as well.  The DataGrid won't work without it.

Quentin "Q" Alldredge

Owner, Q Software Innovations, LLC (QSI) | Director, GCentral | Admin, LabVIEW Wiki
Tech Lead, Hill AFB LabVIEW Center of Excellence | Creator, The QControl Toolkit
Certified LabVIEW Architect | LabVIEW Champion | NI Alliance Partner


0 Kudos
Message 27 of 36
(481 Views)

Thanks for both the answer here and in the Idea Exchange- I think I've got it rolling now. Couple more questions- first, can I capture a value change event in the main program when the user edits a value? It looks like the Value Change event is triggering when the user double-clicks the row, but not after typing in a value. Second, is there an easy way for a user to delete a row?

0 Kudos
Message 28 of 36
(475 Views)

I’ll be honest... The DataGrid might be missing a feature or two as it was a proof of concept for edit time behavior in a QControl. I’ll take your feedback though and any other suggestions you have.

Or if you want to run with it and add your own features, I’d love to see it. 

To answer your questions though:

I didn’t add any special Value Change behavior so it acts like a traditional MCLB at this point. But I have experimented in another QControl with creating a User Event in the constructor VI and passing that to my main VI to register for. Then I generate the User Event in the Event Handler when something special happens. I’ll try to find which one I did that in to show you. 

No, I did not add a way to delete a row but that was on my to do list. 

Quentin "Q" Alldredge

Owner, Q Software Innovations, LLC (QSI) | Director, GCentral | Admin, LabVIEW Wiki
Tech Lead, Hill AFB LabVIEW Center of Excellence | Creator, The QControl Toolkit
Certified LabVIEW Architect | LabVIEW Champion | NI Alliance Partner


0 Kudos
Message 29 of 36
(470 Views)

I have experimented in another QControl with creating a User Event in the constructor VI and passing that to my main VI to register for. Then I generate the User Event in the Event Handler when something special happens. I’ll try to find which one I did that in to show you. 


Ok I remember... it was the BreadcrumbNavigator QControl found here:

 

https://labviewwiki.org/wiki/BreadcrumbNavigator_QControl

 

It has a special User Event called "ClickedItemEvent" that your main program registers for.  This way, in the Event Handler, I fire the event when the item was clicked on and return the string of that item.

 

QControls are flexible.  For everyones benefit I would like to post that there are only a few rules:

 

  1. The new QControl class must ultimately inherit from the Control class from the QControl Toolkit.  This is how the launching of the Event Handler is instigated.  Inheritance from other classes in the hierarchy is how you get the other Properties and Methods.
  2. The constructor VI (created by the wizard) must call the Load Reference, Load State Data, and Initialize Control methods and each of those must call parent method.  You can add custom stuff to each and to the constructor if desired.  These methods are how:
    • The inheritance of the Properties and Methods are available to you 
    • The State Data is kept in sync between your custom properties/methods and the Event Handler
    • The Control class launches your Event Handler
  3. Pass the QControl class wire the same way you would pass around a reference wire.  You shouldn't pass around the reference wire too, but nothing is stopping you from doing so.  Obviously, you won't have access to your custom properties through the reference wire and keep in mind if you change a property through the reference wire and not the QControl class the QControl class might not know about the change depending on what property it was and what your Event Handler does when properties change.
  4. You should close a QControl with the destructor VI.  There is code to catch orphaned Event Handlers but it is still best practice.
  5. Only reference types should be part of the class private data.  These classes should be treated as a reference themselves so by definition they are "by-reference" classes.

 

Some things that are flexible include:

 

  1. You don't necessarily need an Event Handler.  I created a ProgressBar QControl where all I wanted to do was change how the color and caption changed through an extended property which could be set to {Pass, Fail, or Completed}.
  2. You can extend your own QControls.  An example of this is the Selection Tree QControl that ships with the toolkit.  Only the parent most one has the Event Handler.  The others just override the toggle selection method.  The same Event Handler code is called for each one but the toggle dynamically dispatches.
  3. You can add other reference types to the class private data.  Like the example above that includes a User Event.
  4. You can have multiple controls in a QControl.  You might have to modify the constructor inputs and be careful which class you inherit from.  There can really be only one inheritance path so make sure the correct reference is passed to the Load Reference method or you'll get errors.  In this case, sometimes I'll inherit from the Cluster control and handle references accordingly.  I do this with the Calendar QControl and the toolbar in the RichTextBox QControl.
  5. There is no problems with having and Array of QControls, but you'll have to handle the complications there because what you'll really have is just the reference to the Array control to inherit from and pass the reference of to the constructor.
  6. You can use other design patterns in the Event Handler as long as you handle the shutdown of your loops properly.

There is probably more but that is all I can think of for now.

Quentin "Q" Alldredge

Owner, Q Software Innovations, LLC (QSI) | Director, GCentral | Admin, LabVIEW Wiki
Tech Lead, Hill AFB LabVIEW Center of Excellence | Creator, The QControl Toolkit
Certified LabVIEW Architect | LabVIEW Champion | NI Alliance Partner


0 Kudos
Message 30 of 36
(467 Views)