Sunday, January 28, 2018

Building Tkinter Interfaces from the Inside Out

Graphical user interfaces (GUIs) ordinarily consist of a number of different elements, such as those illustrated in Figure 1. Some GUI development toolkits, specifically including Python's Tkinter module, require these elements to be assembled from the outside in. That is, the outermost frame must be defined first, and that first frame then populated with any container elements (e.g., additional frames), and then those second-level frames populated next, and so forth.
Figure 1. Sketch of example GUI.

Such an interface may be easier to describe from the inside out, though, rather than from the outside in. For example, the GUI shown in Figure 1 could be described as:

group_1 ← column_of (topic_selection, date_selection)
group_2 ← row_of (group_1, format_options)
group_3 ← column_of (header, group_2, output_selection, buttons)

The group_3 element then describes the entire GUI, including the nested hierarchy of other elements.

The TkLayout Python package allows GUIs to be built by describing them in just this way. The key to this process is separation of the steps of describing the interface and creating the interface.

To describe the interface, the GUI implementer must first assign a name to each element of the GUI. For the example shown in Figure 1, reasonable names would be "topic_selection", "date_selection", etc. The interface is then described using methods of an AppLayout object as follows:

group_1 = column_elements("topic_selection", "date_selection")
group_2 = row_elements(group_1, "format_options")
group_3 = column_elements("header", group_2, "output_selection", "buttons")


The row_elements and column_elements methods synthesize and return new element names that identify the element groupings that are created—i.e., group_1, group_2, and group_3. After the structure of the GUI has been described, the frames that implement that structure are created with another method of the AppLayout object, as follows:

create_layout(root, group_3)

where the root argument is a Tkinter top level object or other container that will contain the GUI.

The create_layout method creates a series of nested frames, as shown in Figure 2 for the GUI illustrated in Figure 1.


Figure 2. Frame hierarchy for the GUI in Figure 1.

After this set of frames is created, the enclosing frame for each element can be obtained from the AppLayout object using that element's name. The GUI implementer can then populate each of these frames with other GUI widgets as appropriate. The AppLayout class will also take a dictionary of element names and element-construction functions, and run those functions to populate each element's enclosing frame.  The functions that create the elements for each frame require only the enclosing frame object, and do not need to know anything about how the elements are laid out in relation to one another.

Separation of structure description and implementation in this way allows the GUI construction process to be greatly simplified.  Exploration of alternate interface layouts is also simplified: each alternate layout can be described in just a few lines of code, without any changes required to code to populate or arrange the interface elements.

The TkLayout package can be downloaded from the Python Package Index (PyPI) or installed with the command

pip install tklayout

The documentation is available on ReadTheDocs.

No comments:

Post a Comment