Designing the application
With our specification in hand and our requirements clear, it's time to start designing our solution. The main focus of our application is the data entry form itself, so we'll begin with that GUI component.
We're going to create a basic design for our form in three steps:
- Determine the appropriate input widget type for each data field
- Group together related items to create a sense of organization
- Lay out our widgets within their groups
Deciding on input widgets
Without committing ourselves to a particular GUI library or widget set, we can start our form design by deciding on an appropriate input widget type for each field. Most toolkits come with the same basic types of inputs for different types of data.
We've already seen some of these in our look at Tkinter, but let's see what sort of options are likely to be available:
Widget type |
Tkinter example |
Used for |
Line entry |
|
Single-line strings |
Number entry |
|
Integer or decimal values |
Select list (drop-down) |
|
Choice between many distinct values |
Check box |
|
True/false value |
Radio button |
|
Choice between a few distinct values |
Text entry |
|
Multi-line text entry |
Date entry |
(None specific) |
Dates |
Looking at our data dictionary, what sort of widgets should we pick out for each of our fields? Let's consider:
- There are several decimal fields, many with clear boundary ranges, like Min Height, Max Height, Median Height, Humidity, Temperature, and Light. We'll need some kind of number entry, perhaps a Tkinter
Spinbox
, for these. - There are also some integer fields, such as Plants, Blossoms, and Fruit. Again, a number entry like the
Spinbox
widget is the right choice. - There are a couple of fields with a limited set of possible values: Time and Lab. For these we could go with radio buttons or a select list of some kind. It really depends on the number of options and how we want to lay it out: radio buttons take a lot of space with more than a few choices, but select list widgets take additional interaction and slow down a user. We'll choose a select/drop-down for the Time field, and radio buttons for the Lab field.
- The Plot field is a tricky case. At face value, it looks like an integer field, but think about it: the plots could just as well be identified by letters, or symbols, or names. Numbers just happen to be an easy set of values with which to assign arbitrary identifiers. The Plot ID, like the Lab ID, is actually a constrained set of values; so, it would make more sense to use a select list here.
- The Notes field is multiline text, so the Text widget is appropriate here.
- There is one Boolean field, Fault. A check box type widget is a good choice here, especially since this value is normally false and represents an exceptional circumstance.
- For the Date field, it would be nice to use a date entry of some sort. We don't know of one in Tkinter yet, but we'll see if we can solve that when we write our application.
- The remaining lines are simple, one-line character fields. We'll use a text entry-type widget for those fields.
Our final analysis comes to the following:
Field |
Widget type |
Date |
Date entry |
Time |
Select list |
Lab |
Radio buttons |
Technician |
Text entry |
Plot |
Select list |
Seed Sample |
Text entry |
Fault |
Check box |
Humidity |
Number entry |
Light |
Number entry |
Temperature |
Number entry |
Blossoms |
Number entry |
Fruit |
Number entry |
Plants |
Number entry |
Max Height |
Number entry |
Median Height |
Number entry |
Min Height |
Number entry |
Notes |
Text entry |
Bear in mind, this analysis is not set in stone; it will almost certainly be revised as we receive feedback from our users, as the application's use case evolves, or as we become more familiar with the capabilities and limitations of Python and Tkinter. This is simply a starting place from which we can create an initial design.
Grouping our fields
Humans tend to get confused when staring at a huge wall of inputs in no particular order. You can do your users a big favor by breaking up the input form into sets of related fields. Of course, that assumes that your data has related sets of fields, doesn't it? Does our data have groups?
Recall some of the information we gathered during our interviews:
- One of the employees requested separate forms for "environmental data" and "plant data"
- The layout of the paper form has Time, Date, Lab, and Technician, all together at the top; these things help identify the data recording session
Details like this tell you a lot about how your users think about their data, and that should inform how the application presents that data.
Considering all this, you identify the following related groups:
- The Date, Lab, Plot, Seed Sample, Technician, and Time fields are identifying data or metadata about the record itself. You could group these together under a heading calling Record Information.
- The Blossoms, Fruit, three Height fields, and Plants fields are all measurements that have to do with the plants in the Plot field. You could group these together under the heading Plant Data.
- The Humidity, Light, Temperature, and Equipment Fault fields are all information from the environmental sensor. You could group these as Environmental Data.
- The Notes field could be related to anything, so it's in a category of its own.
Most GUI libraries offer a variety of ways to group sections of a form together; think of some you have seen. A few are listed in this table:
Widget type |
Description |
Tabs (notebook) |
Allows multiple tabbed pages that the user can switch between |
Frames/boxes |
Draws boxes around sections of a form, sometimes with a header |
Accordion |
Divides a form into sections that can be hidden or expanded one at a time |
Framed boxes are the simplest way to break up a GUI. In cases where there are a lot of fields, a tabbed or accordion widget can help by hiding fields the user isn't working with. However, they require additional user interaction to switch between pages or sections. You decide, after some consideration, that framed boxes with headers will be perfectly adequate for this form. There are not really enough fields to justify separate pages, and switching between them would just add more overhead to the data entry process.
Laying out the form
So far, we know that we have 17 inputs, which are grouped as follows:
- Six fields under Record Information
- Four fields under Environmental Data
- Six fields under Plant Data
- One large Notes field
We want to group the preceding inputs using some kind of box or frame with a header label. Notice that two of the first three sections have widgets in multiples of three. That suggests that we could arrange them in a grid with three items across. How should we order the fields within each group?
Ordering of fields seems like a trivial item, but for the user it can make a significant difference in usability. Users who have to jump around a form haphazardly to match their workflow are more likely to make mistakes.
As you learned, the data is entered from paper forms filled out by the lab technicians. Refer back to the screenshot of the paper form shown in Figure 2.1 in the previous section. It looks like items are mostly grouped the way our records are grouped, so we'll use the ordering on this form to order our fields. That way, data entry clerks can zip right through the form from top to bottom, left to right, without having to bounce around the screen.
Remember, user workflow is important! When designing a new application to replace some part of an existing procedure, it's crucial to respect the established workflow. While improving the status quo may require adjusting the workflow, be careful that you aren't making someone else's job harder without a good reason.
One last consideration in our design is where to place field labels in relation to the fields. There is a good deal of debate in the UI design community over the best placement of labels, but the consensus is that one of the following two options is best:
- Labels above fields
- Labels to the left of fields
You might try sketching out both to see which you prefer, but for this application, labels above fields will probably work better for the following reasons:
- Since both fields and labels are rectangular in shape, our form will be more compact by stacking them
- It's a lot easier to make the layout work, since we don't have to find a label width that works for all the labels without distancing them too far from the fields
The one exception is the check button field; check buttons are typically labeled to the right of the widget.
Take a moment to make a mockup of your form, using paper and pencil, or a drawing program if you prefer. Your form should look something like this:
Figure 2.3: The form layout
Laying out the application
With your form designed, it's time to consider the rest of the application's GUI:
- You'll need a save button to trigger storage of the entered data.
- It's customary to include a button to reset the form, so the user can start over if needed.
- Sometimes, we might need to provide status information to the user. For example, we might want to let them know when a record was successfully saved, or if there is an error in a particular field. Applications typically have a status bar that displays these kinds of messages at the bottom of the window.
- Finally, it might be good to have a header indicating what the form is.
Adding the following things to our sketch, we have something like the following screenshot:
Figure 2.4: The application layout
Looks good! Your final step is to show these designs to your users and the director for any feedback or approval. Good luck!
Keep stakeholders – your boss, users, and others who will be affected by your program – involved as much as possible in your application design process. This reduces the possibility that you'll have to go back and redesign your application later.