Improving the accessibility of Python-based research software
This project is maintained by ImperialCollegeLondon
The following import statements need to be called before importing the widgets below:
import ipywidgets as widgets
from tkinter import ttk
and for some older widgets:
import tkinter as tk
Each widget lives in its own submodule of uix
:
from kivy import uix
The above widgets do not exist on their own: they all need to be placed within a container (can be the top window of the application) and arranged in a certain way within the container. This task is performed by container/layout widgets.
The basic containers are vertical and horizontal boxes that can host several widgets in a row (HBox and VBox for Jupyer and BoxLayout or GridLayout for Kivy). The way of using them is:
Example: The labels are placed next to each other left to right, with 0 on the left and 3 on the right. Note that hbox
also has to be added to a container, unless it is the top container.
# Jupyter Widgets
hbox = widgets.HBox()
hbox.children = [widgets.Label(str(i)) for i in range(4)]
# Kivy
hbox = uix.boxlayout.BoxLayout()
for i in range(4):
hbox.add_widget(uix.label.Label(text=str(i)))
3: Note that Kivy has a large variety of specialised layouts that do not follow the above description and that, ultimately, allow the user to put the widgets wherever they want using relative or absolute coordinates.
In Tkinter, how things are arranged do not depend on the container (which will be ttk.Frame
most of the times) but on the geometry manager used. The process in this case will be:
Pack
geometry manager works like Jupyter Widgets and Kivy containers, arranging widgets automatically in the order they are being packed, either vertically or horizontally.Grid
geometry manager allows to specify exact row and column for the children widgets, how many of these they should span as well as how they should resize with the container.tk.Tk
main window, from which all children hang.Example: For the Pack
manager, the labels are placed next to each other left to right, with 0 on the left and 3 on the right. For the Grid
manager, a specific row and column is chosen, in this case filling a diagonal. Note that hbox
also has to be packed or grid in order to have it visible.
# Using Pack
hbox = ttk.Frame(master=parent_container)
for i in range(4):
ttk.Label(master=hbox, text=str(i)).pack(side=tk.LEFT)
# Using Grid
hbox = ttk.Frame(master=parent_container)
for i in range(4):
ttk.Label(master=hbox, text=str(i)).grid(column=i, row=i)
4: Like the specialised Kivy layouts, Tkinter also has the Place
geometry manager that allows to place the widgets virtually anywhere in absolute or relative terms.
Notebook (Jupyter Widgets and Tkinter) and PageLayout (Kivy) are both used to create a tab-based or multi-page layout, with the possibility of changing to one another by clicking on the tab/page border.
In both cases, it is recommended - although not necessary - that each of the tabs/pages to be a container/layout widget itself as those shown above with as many children widgets as needed.
Jupyter Widgets notebook with 3 tabs:
hbox1 = widgets.HBox()
hbox2 = widgets.HBox()
hbox3 = widgets.HBox()
book = widgets.Tab()
book.children = [hbox1, hbox2, hbox3]
Tkinter notebook with 3 tabs:
book = ttk.Notebook(master=parent_container)
hbox1 = ttk.Frame(master=book)
hbox2 = ttk.Frame(master=book)
hbox3 = ttk.Frame(master=book)
book.add(hbox1)
book.add(hbox2)
book.add(hbox3)
Kivy PageLayout with 3 pages:
hbox1 = uix.boxlayout.BoxLayout()
hbox2 = uix.boxlayout.BoxLayout()
hbox3 = uix.boxlayout.BoxLayout()
book = uix.pagelayout.PageLayout()
book.add_widget(hbox1)
book.add_widget(hbox2)
book.add_widget(hbox3)