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 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', alignment=toga.LEFT_ALIGNED) f_label = toga.Label('Fahrenheit', alignment=toga.LEFT_ALIGNED) join_label = toga.Label('is equivalent to', alignment=toga.RIGHT_ALIGNED) def calculate(widget): try: c_input.value = (float(f_input.value) - 32.0) * 5.0 / 9.0 except: c_input.value = '???' button = toga.Button('Calculate', on_press=calculate) f_box.add(f_label) f_box.add(f_input) 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(flex_direction='column', padding_top=10) f_box.style(flex_direction='row', margin=5) c_box.style(flex_direction='row', margin=5) c_input.style(flex=1) f_input.style(flex=1, margin_left=160) c_label.style(width=100, margin_left=10) f_label.style(width=100, margin_left=10) join_label.style(width=150, margin_right=10) button.style(margin=15) return box if __name__ == '__main__': app = toga.App('Temperature Converter', 'org.pybee.f_to_c', startup=build) app.main_loop()
This example shows off the use of Flexbox in Toga's CSS styling. Flexbox is a new layout scheme that is part of the CSS3 specification that corrects the problems with the older box layout scheme in CSS2. Flexbox is not yet universally available in all web browsers, but that doesn't matter for Toga - Toga provides an implemention of the Flexbox layout scheme. CSS-tricks provides a good tutorial on Flexbox if you've never come across it before.
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 the 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.