.. TkLayout documentation master file. .. role:: raw-html(raw) :format: html TkLayout ************************************************************* TkLayout is a Python library that simplifies the development of Tkinter applications that have a complex layout of widgets. Simplification is achieved by separating the description of the interface structure from the construction of the nested frames that implement that structure. .. toctree:: :maxdepth: 1 :caption: Contents: Purpose ============================================================== The purpose of the `tklayout` library is to allow the developer of a Tkinter GUI to easily specify the layout of UI widgets, or groups of widgets, and then to automatically create and populate the nested frames necessary to implement the specified layout. Usage ============================================================== The usage pattern to be followed when using this library is as follows: 1. Design the layout and assign a name to each layout element. An example is shown in Figure 1. .. _figure_sketch: .. figure:: figure_1.png :align: center :height: 180pt :alt: Layout sketch with named elements Figure 1. Layout sketch with named elements 2. Instantiate an object of the AppLayout class from the `tklayout` library. 3. Identify layout elements that will appear in the same column or row, and, working from the innermost grouping to the outermost, tell the AppLayout object about all of those relationships, using the ``column_elements()`` and ``row_elements()`` methods. 4. Tell the AppLayout object to create a set of nested frames that conform to the specified layout groupings, using the ``create_layout()`` method. 5. Tell the AppLayout object which functions to run to populate the named frames with the appropriate widgets, using the ``build_elements()`` method. In all interactions with the AppLayout object, layout elements are referred to by the names assigned in step 1 above, and as shown in :ref:`Figure 1 `. In step 3 above, the first elements in Figure 1 that would be identified as being grouped together would be the *topic_selection* and *date_selection* elements. The second grouping to be identified would be the combination of the previous two with the *format_options* element. Although Tkinter frames must be created from the outside in (i.e., the largest enclosing frame must be created first), the "inside-out" method of describing the layout of user interface elements may be easier to visualize and to use. The UI implementer does not need to keep track of all of the frame objects that are used in the layout. The frame objects that enclose the user-specified elements can be obtained from the AppLayout object using the ``frame()`` method, identifying the element of interest by name. Other methods that support access to frames and their elements after the nested set of frames has been built are: * ``build_element()``: This allows a build function to be specified (and run) for a single named UI element. * ``frame_widgets()``: This returns the list of all of the elements within the frame enclosing a user-specified element. The AppLayout Class ============================================================== Creating a Tkinter layout is done with the ``AppLayout`` class in the ``tklayout`` module. .. module:: tklayout .. autoclass:: AppLayout :members: Example ============================================================== The following code is a simple usage of the ``tklayout`` module to demonstrate the use of the ``AppLayout`` class and its methods. .. code-block:: python try: import Tkinter as tk except: import tkinter as tk import tklayout as tkb def test(): # Define functions to build each of the user-defined elements # that will appear in the application. (These 'build' functions # are nested within the 'test' function, but need not be.) # Build element A. def build_a(parent): w = tk.Label(parent, text="Element A", justify=tk.CENTER) w.grid(row=0, column=0, padx=10, pady=5, sticky=tk.NSEW) # Build element B. def build_b(parent): w = tk.Label(parent, text="Element B", justify=tk.CENTER, fg="blue") w.grid(row=0, column=0, padx=10, pady=5, sticky=tk.NSEW) parent.rowconfigure(0, weight=1) parent.columnconfigure(0, weight=1) # Build element C. def build_c(parent): w = tk.Label(parent, text="Element C", justify=tk.CENTER) w.grid(row=0, column=0, padx=10, pady=5, sticky=tk.NSEW) parent.rowconfigure(0, weight=1) parent.columnconfigure(0, weight=1) # Build element D. def build_d(parent): w = tk.Label(parent, text="Element D", justify=tk.CENTER, fg="green") w.grid(row=0, column=0, padx=5, pady=5, sticky=tk.EW) # Build element E. def build_e(parent):html copyright entity w = tk.Label(parent, text="Element E", justify=tk.CENTER) w.grid(row=0, column=0, padx=5, pady=5, sticky=tk.NSEW) # Initialize the application layout object. lo = tkb.AppLayout() # Define configuration and gridding options that will be used # for the frames that enclose the user-defined elements. config_opts = {"borderwidth": 3, "relief": tk.GROOVE} grid_opts = {"sticky": tk.NSEW} # Define the structure of the application elements. ab = lo.column_elements(["A", "B"], config_opts, grid_opts) abc = lo.row_elements([ab, "C"], config_opts, grid_opts) app = lo.column_elements(["D", abc, "E"], config_opts, grid_opts, row_weights=[0,1,1]) # Create the Tkinter root object. root = tk.Tk() # Create the frames implementing the specified layout. lo.create_layout(root, app, row=0, column=0, row_weight=1, column_weight=1) # Fill in the user-defined element frames with widgets. lo.build_elements({"A": build_a, "B": build_b, "C": build_c, "D": build_d, "E": build_e}) # Run the application. root.mainloop() test() This will produce an application window with the layout shown below. .. figure:: example_1.png :align: center :alt: Example Layout Figure 2. Example Layout Frame borders are used in this example to illustrate the nested set of frames that is created by ``create_layout()``. The layout of the UI elements can be easily altered just by changing the calls to ``column_elements()`` and ``row_elements()``. For example, changing the calls to the ``row_elements()`` and ``column_elements()`` methods in the previous script with this set of method calls: .. code-block:: python cb = lo.column_elements(["C", "B"], config_opts, grid_opts) ae = lo.column_elements(["A", "E"], config_opts, grid_opts) cbae = lo.row_elements([cb, ae], config_opts, grid_opts) app = lo.column_elements([cbae, "D"], config_opts, grid_opts) will produce a different layout for the same application, as shown below. .. figure:: example_2.png :align: center :alt: Alternative Layout Figure 3. Alternative Layout Notes ================================================================ Geometry Managers ----------------------------------------- The ``build_layout()`` method uses the *grid* geometry manager for all frames that it creates. However, the *pack* and *place* geometry managers can be used instead to populate any of the frames that enclose user-defined elements. Resizing ---------------------------------------- By default, all frames are made resizeable. Every row and column is given a weight of 1, and every frame is made sticky to its N, S, E, and W enclosing frame. This default differs from Tkinter's: Tkinter by default does not not create or grid frames so that they are automatically resizeable. The default for the AppLayout class differs because resizing is frequently desirable, and it is generally easier to suppress resizing than it is to enable it. The default weights and configuration options can be changed with the optional arguments to the ``row_elements()``, ``column_elements()``, and ``build_elements()`` methods. Availability ================================================================ The TkLayout library is available on `PyPi `_. It can be installed with: .. code-block:: none pip install tklayout Releases are also available from `OSDN `_. .. include:: ../../CHANGELOG.rst Copyright and License ================================================================ Copyright :raw-html:`©` 2018, R.Dreas Nielsen This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. The GNU General Public License is available at http://www.gnu.org/licenses/. Index ================== * :ref:`genindex`