-
Notifications
You must be signed in to change notification settings - Fork 2
Conceptual Overview
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 ofElement
s inside it, like text and buttons. Some of the elements contain other elements, in a tree structure: for example, myGrid
element contains a fewEmphasizedText
s (for the headers) and a fewTextField
s (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 executemy_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 thatmy_function()
is called whenever the user clicks the button;my_dropdown.change_callback = my_function()
will callmy_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
- one
- 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 alist
-
you can call a GUI's
run()
method to start it running, likeGUI(Text('Hello, world!')).run()