Skip to content

Conceptual Overview

speezepearson edited this page Nov 15, 2015 · 1 revision

Roughly speaking, here's a good way to think about a GUI created with this package.

I have a GUI instance. The GUI has a bunch of Elements inside it, like text and buttons. Some of the elements contain other elements, in a tree structure: for example, my Grid element contains a few EmphasizedTexts (for the headers) and a few TextFields (for the cells).

Modifying the elements causes them to be drawn differently in the browser. For example, when I execute my_list.numbered = True, the list markers change from bullets to numbers. When I execute my_list.append(Text("new last item")), a new item will appear in the list in the browser.

I can attach callbacks to certain elements to gather user input. For example, by executing my_button.callback = my_function, I ensure that my_function() is called whenever the user clicks the button; my_dropdown.change_callback = my_function() will call my_function() whenever the dropdown's value changes (either because the user interacted with it, or because some code set its .value property).

Just like in other GUI frameworks: the state of the user interface is represented by some data structure; modifying the data structure causes stuff to be redrawn on the screen; and functions can be attached to the data structure, to be called when the user interacts with the GUI in certain ways (e.g. clicking on buttons, typing things, etc.).

Each widget on the screen (e.g. buttons, pieces of text, tables, lists) is an Element. Elements are arranged in a tree structure, i.e. each Element typically has exactly one parent, which represents some widget that contains the child widget on the screen. For example:

text_1 = Text('one')
text_2 = Text('two')
list = List(items=[text_1, text_2])

All three variables are Elements (Text and List are subclasses of Element). list is the parent of the text elements, and it has no parent. When displayed, list will look like

  • one
  • two

Modifying an Element always immediately causes it to be redrawn in the browser. For example, if list is being displayed in a browser, executing list.numbered = True will immediately change the browser to display it as

  1. one
  2. two

Some Elements (e.g. buttons, input fields) allow callback functions to be attached to them, so that the function is called whenever the user interacts with them in some way (e.g. clicking, typing). This is accomplished either by passing the function as an argument when instantiating the Element, e.g.

b = Button(callback=lambda: print("Click!"))
t = TextField(change_callback=lambda: print(t.value))

or by setting one of the Element's attributes, e.g.

b.callback = (lambda: print("Click!"))
t.change_callback = (lambda: print(t.value))

The last important concept is the GUI. The GUI class is responsible for high-level stuff that doesn't belong to any individual element, e.g. setting the page title and alerting the server when an element changes. Pretty much all you need to know about the GUI class is:

  • you instantiate it like

    GUI(element_1, ..., title='Browser page title')
  • gui.body is an Element that you can index/modify/iterate over like a list

  • you can call a GUI's run() method to start it running, like

      GUI(Text('Hello, world!')).run()
    
Clone this wiki locally