.. _custom-widgets: Extending Taurus widgets ======================== There are several levels at which a Taurus GUI can be customized. The highest level is to build a :ref:`TaurusGUI application ` from existing Taurus or third-party widgets and attach models to them. Existing widgets can also be combined or configured directly, either programmatically or with :ref:`Qt Designer `. When the required functionality is not provided by an existing widget, a new widget can be created. Widgets that interact with Taurus models typically combine a :class:`QWidget` (or another QWidget-derived class) with :class:`taurus.qt.qtgui.base.TaurusBaseComponent` or one of its derived mixin classes. The Taurus base component classes provide APIs commonly expected from Taurus widgets, including: - model support - configuration - logging - formatting This composition is sometimes informally described as *Taurus-ifying* a Qt class. The mixin handles model attachment and subscription, while the widget implements the behaviour required when model events are received. See :ref:`howto-custom-widgets` for a practical example. As a general rule, use the highest-level customization mechanism that satisfies your requirements and keep custom code as small and reusable as possible. For example, if an application needs a specialized control widget, it is usually preferable to implement only that widget and embed it in a TaurusGUI rather than implementing the whole application from scratch. .. _multi-model: Multi-model support ------------------- Before Taurus TEP20_ (implemented in Taurus 5.1), :class:`taurus.qt.qtgui.base.TaurusBaseComponent` and its derived classes only provided support for a single model associated with a QWidget or QObject. Widgets requiring more than one model therefore had to implement their own multi-model mechanisms. With TEP20_, Taurus base classes support multiple models by assigning keys to models. A widget defines the supported model keys with ``modelKeys``. The first key is used as the default when a model API method is called without explicitly specifying a key. The model API also supports widgets operating on a list of models through the special ``MLIST`` key, available from :mod:`taurus.qt.qtgui.base` and as ``TaurusBaseComponent.MLIST``. When ``setModel`` is called with ``key=MLIST``, the model argument is expected to be a sequence of model names. Taurus creates model keys of the form ``(MLIST, i)`` and attaches the corresponding models using those keys. A common use of ``MLIST`` is a model-delegate container. Such a widget can create Taurus child widgets dynamically and delegate each model to one of those children instead of handling all model events itself. :class:`TaurusForm` uses a similar delegation pattern. See :ref:`howto-custom-widgets` for examples of single-model, multi-model, and model-list widgets. .. _TEP20: https://gitlab.com/taurus-org/taurus/-/blob/develop/doc/source/tep/TEP20.md