A slightly less toy example#
Note
Toga is a work in progress, and may not be consistent across all platforms.
Please check the Tutorial Issues label on GitHub to see what’s currently broken.
Most applications require a little more than a button on a page. Lets build a slightly more complex example - a Fahrenheit to Celsius converter:

Here’s the source code:
import toga
from toga.style.pack import COLUMN, LEFT, RIGHT, ROW, Pack
def build(app):
c_box = toga.Box()
f_box = toga.Box()
box = toga.Box()
c_input = toga.TextInput(readonly=True)
f_input = toga.TextInput()
c_label = toga.Label("Celsius", style=Pack(text_align=LEFT))
f_label = toga.Label("Fahrenheit", style=Pack(text_align=LEFT))
join_label = toga.Label("is equivalent to", style=Pack(text_align=RIGHT))
def calculate(widget):
try:
c_input.value = (float(f_input.value) - 32.0) * 5.0 / 9.0
except ValueError:
c_input.value = "???"
button = toga.Button("Calculate", on_press=calculate)
f_box.add(f_input)
f_box.add(f_label)
c_box.add(join_label)
c_box.add(c_input)
c_box.add(c_label)
box.add(f_box)
box.add(c_box)
box.add(button)
box.style.update(direction=COLUMN, padding=10)
f_box.style.update(direction=ROW, padding=5)
c_box.style.update(direction=ROW, padding=5)
c_input.style.update(flex=1)
f_input.style.update(flex=1, padding_left=160)
c_label.style.update(width=100, padding_left=10)
f_label.style.update(width=100, padding_left=10)
join_label.style.update(width=150, padding_right=10)
button.style.update(padding=15)
return box
def main():
return toga.App("Temperature Converter", "org.beeware.f_to_c", startup=build)
if __name__ == "__main__":
main().main_loop()
This example shows off some more features of Toga’s Pack style engine. In this example app, we’ve set up an outer box that stacks vertically; inside that box, we’ve put 2 horizontal boxes and a button.
Since there’s no width styling on the horizontal boxes, they’ll try to
fit the widgets they contain into the available space. The TextInput
widgets have a style of flex=1
, but the Label
widgets have a fixed
width; as a result, the TextInput
widgets will be stretched to fit the
available horizontal space. The margin and padding terms then ensure that the
widgets will be aligned vertically and horizontally.