Sunday, October 16, 2011

Nexsys: Main Window Ui (Part III)

At this point we have a pretty well blocked out interface for our main window.  There are still a couple more steps that we're going to do in designer before we jump back into the, to make sure we get the most out of our interface builder.

Setting up Checkable Actions

Some of our actions that we defined we need to be able to toggle on and off.  For these actions, we'll need to set them as checkable.

If you click on your Settings menu in your window, it'll highlight the ui_settings_menu object in your Object Browser.

This is a quick way to jump to one of your objects - selecting in the UI will select in the browser, and vice versa.  From here, select all the 'ui_show*_act' actions (should be ui_showfucs_act, ui_showcmd_act, uishowstatus_act, ui_showtools_act actions) and go down to the Property Editor.

What we're going to do is link these actions to turning on and off the visible state for our different widgets.  So we're going to want these actions to be able to be on/off.

The very first property is checkable so click that on.  Now, all 4 of those actions are checkable.  The next thing we want to do is say that they are by default visible (since we can still see our widgets), so click the next property, checked, on as well.

If you look at the actions in your window, they now have a check on/off state next to them, and if you preview your window, you can see that you can toggle their state.

Lets also turn our ui_verticalmode_act to a checkable state, but lets leave that one off.

We're also going to turn the ui_showhidden_act as a checkable action, and leave it off, and turn both the ui_showdetails_act and ui_showbrief_act as checkable, leaving the details on and brief off.  We're going to actually use those two as a radio button actions because we want to only let one of those state be on at a time - but we'll do that in a minute.

Creating Connections

The next thing we're going to do is make a couple of connections that we don't need to have at the code level.  If you remember the signal/slot article from a couple posts back - Qt control's its information via events that are emitted from one object and listened to by another.

The Qt Designer provides an interface for connecting those signals and slots together via the UI.

So far, all of the work that we have done has been with the Designer in Edit Widgets mode.  Now, we're going to switch over to Edit Signals/Slots.

This is done by clicking on the Edit Signals/Slots button in the Tool toolbar.

This would be the 2nd icon in the list.  The other ones are Edit Buddies (which I have yet to get to work - in 4.5.3 at any rate), and the Edit Tab Order which we'll use in a minute.

With the Edit Signals/Slots turned on, when you hover over a widget, you'll now see a Red highlight box show up.  This will allow you to drag & drop a connection between two widgets based on their exposed signals and slots.

Unfortunately - we can't really use the drag & drop connection right now, cause we're creating connections from our actions to our widgets - so you'll have to look for the Signal/Slot Editor.  This would be another edit pane, usually tabbed undeneath the Property Editor on the right hand side of designer.  For some more help, check out the Qt documentation.

The first connection we'll make is between our 'ui_showcmd_act' and our 'ui_cmdline_widget' widget.  We'll want to link the visible state of the widget to the toggle state of the action.  To do this, we'll click on the big green '+' icon in the editor to add a new connection.  (I often find it better to pop this widget off as a floating window to make it wide enough to work with).

With the new connection selected choose:
  1. For Sender, pick 'ui_showcmd_act' from the list of objects
  2. For Signal, pick 'triggered(bool)' from the list of signals
  3. For Receiver, pick 'ui_cmdline_widget' from the list of objects
  4. For Slot, pick 'setVisible(bool)' from the list of slots
So that's it - you just made your first Designer connection!  If you Preview your form now (Ctrl+R) and toggle the Show Command Line action on and off, you'll see your widget show and hide properly.

See if you can create a new similar connection between the 'ui_showfuncs_act' and the 'ui_funcs_widget'.  At this point, rename the 'statusbar' widget that is defaulted from the QMainWindow to 'ui_main_status' and create a similar connection from 'ui_showstatus_act' to it.

Side Note: While there are a couple thoughts on this, my general preference is to handle user interface level connections (such as enabling and disabling, hiding and unhiding, etc.) at the designer level, while handle the creation of connections to more controller logic in the Python code itself.  There are ways to create custom connections to methods from your Python code in the Designer - but I find that is a little dangerous as it mixes the View and Controller layer.  I say any exposed Qt slot to the designer is fair game, since the Python code has to explicitly mark it as a Ui visible method to remind the developer that widgets may connect to it, but any custom code is off limits.

Make the Command Line Editable

As of right now, we have a combo box for our command line utility, however, it doesn't do us much good if the user can't type anything into it.

We could have used a QLineEdit instead, however then we wouldn't have had the option to remember previously typed commands.

One of the nice features to the QComboBox is the ability to make it Edtiable, exposing a built-in QLineEdit to prompt for user input - its just defaulted to not use it.

If you select your 'ui_cmdline_combo', scroll down until you see the edtiable property and click it on.  You'll now see an edit area for a user to type into.  Depending on what you want to do, there are some other options that go with this property - namely the insertPolicy and duplicatesEnabled properties.  Using those, you could for instance ensure that a user can only use the field to search forced entries, vs. typing new entries.  For our purpose, we want the user to be able to add entries, and not let them duplicate entries - so we'll leave the settings as is.

Coming up Next

Next up - we're going to finish up the Main Window Ui by adding some resources and icons to the interface, and connecting the actions up to a toolbar.  After that - it'll be back into the code!

But, just look at all that can be accomplished without even altering your code at all!  If you run your application right now, you'll have your interface, and already have some actions connected up to control the view layer.

1 comment:

  1. Just FYI, you might have a few typos on the last paragraph under "Setting up Checkable Actions". Specifically the following (according to Nexsys: Main Window Ui), just for FYI:

    ui_showhidden_act --> ui_viewhidden_act
    ui_showdetails_act --> ui_viewdetails_act
    ui_showbrief_act --> ui_viewbrief_act

    Excerpt from Nexsys: Main Window Ui:
    2. &View, rename to ui_view_menu
    &Detailed View, rename to ui_viewdetails_act
    &Brief View, rename to ui_viewbrief_act
    Add Separator
    Show &Hidden Files, rename to ui_viewhidden_act
    Add Separator
    &Refresh, rename to ui_viewrefresh_act