Core Principles
- Value-added wrapping: Custom
Binder
classes should only manually wrap
the Qt API when it adds value. For example, translating Qt enums one-to-one
to an ad hoc toolkit-neutral form does not add value. Binder
can
automatically wrap all Qt properties, signals, and slots. This means that
a user of the custom subclass can access everything that the Qt widget
exposes even if the author did not think to expose it. Value-added wrapping
encapsulates patterns of communication and coordinates multiple moving
pieces internal to the widget to expose a bindable Traits API.
- Thin, transparent wrapping: This is a library for using Qt to build
UIs, not hide it behind a toolkit-neutral abstraction.
- Small core: The core should remain tiny so that it can be understood and
traced through by users of QtBinder who are debugging their code.
- Graded transition from Traits UI:
Bound
is a straightforward
Traits UI Item
that can be used wherever any other Item
could be used in
Traits UI. It can be used in a very focused manner to fix one or two places
where the extra flexibility of QtBinder is necessary and ignored elsewhere.
It can also be used to provide the whole View
when desired. Use of
QtBinder should not be held up because we have not added enough value-added
widgets yet.
- Bind to existing instances: All
Binder
classes can either instantiate
their underlying QWidget
or be provided an existing one. This allows us to
lay out an entire UI in Qt Designer, instantiate it from the .ui
file,
then attach the desired Binder
to individual widgets inside of it.
- Do one thing well: Custom
Binder
subclasses should attempt to
encapsulate one particular pattern of using their wrapped widget. It should
not try to switch between different patterns based on configuration (unless
if the intended pattern requires that the widget switch behaviors live). The
logic needed to synchronize the widget state with the model state can
sometimes get hairy. Dealing with multiple patterns conditionally
complicates this part of the code, which makes it harder to customize for
new purposes.
- Pay for what you use:
Binder
wraps all Qt signals, but it will only
connect to them and incur the cost of converting the signal values to Python
objects when a Traits listener is attached to the signal trait.