- 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.
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
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
- Bind to existing instances: All
Binder classes can either instantiate
QWidget or be provided an existing one. This allows us to
lay out an entire UI in Qt Designer, instantiate it from the
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
- 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.