Widgets are components¶
Widgets are what we call “components”, which are a central part of the event system. They are what allows widgets to have properties and react to things happening in other parts of the application. But let’s not get ahead of ourselves; the event system is dicsussed in the next chapter.
For the moment, it’s enough to know that the
class is kind of
thing is that you can use widget objects in Python, by setting their properties,
invoking their actions, and reacting to their state. This is possible because
of so-called proxy objects.
PyComponent and JsComponent¶
- They are both associated with a
- They have an
idattribute that is unique within their session, and a
uidattribute that is globally unique.
PyComponentcan only be instantiated in Python, a
JsComponentmay have a proxy object in Python; these proxy objects are created automatically when Python references the component.
In practice, you’ll use
PyComponents to implement Python-side behavior,
allows a variety of ways by which you can tie Python and JS together, but
this can be a pitfall. It’s important to think well about what parts of your
are discussed later in the guide.
The proxy components allow the “other side” to inspect properties, invoke actions and connect to events. The real component is aware of what events the proxy reacts to, and will only communicate these events.
The example below may be a bit much to digest. Don’t worry about that. In most cases things should just work.
from flexx import flx class Person(flx.JsComponent): # Lives in Js name = flx.StringProp(settable=True) age = flx.IntProp(settable=True) @flx.action def increase_age(self): self._mutate_age(self.age + 1) class PersonDatabase(flx.PyComponent): # Lives in Python persons = flx.ListProp() @flx.action def add_person(self, name, age): p = Person(name=name, age=age) self._mutate_persons([p], 'insert', 99999) @flx.action def new_year(self): for p in self.persons: p.increase_age()
In the above code, the
database object that keeps a list of them lives in Python. In practice,
Person components will e.g. have a visual representation in the
browser. The database could also have been a
JsComponent, but let’s
assume that we need it in Python because it synchronizes to a mysql
database or something.
We can observe that the
add_person action (which executes in Python)
Person objects. Actually, it instantiates proxy objects that
automatically get corresponding (real)
new_year action executes in Python, which in turn invokes the
the example above, we would have to get the
database object into a JsComponent. For example:
The root component¶
Another useful feature is that each component has a
root attribute that
holds a reference to the component representing the root of the application.
E.g. if the root is a
JsComponent objects have a
reference to (a proxy of) this database.