This is a joint blog post by me and Martin Durant.
Panel is an open-source python library that lets you create custom interactive web apps and dashboards by connecting user-defined widgets to plots, images, tables, or text. It is a high-level app and dashboarding solution for python.
Panel supports the following ways to send messages between visual elements:
- Interact: given a function, auto generate widgets for its inputs, and execute on any change
- Reactive: declaratively link functions by specifying which widget values they depend on
- Parameterized class: declare the types and validation for the attributes of a class, and automatically create widgets which then activate methods upon change (see param)
- Widget linking: have values propagated from one widget to another, with optional validation
- Watch: assign arbitrary callback functions to any change of a property of any widget. This is by far the most general and low-level method, but also unstructured and therefore complex: a fully-functioning interface might have many such callbacks defined.
Besides having several ways to link widget with a callback, users still need something to handle much more complexity with ease. So cheers, since Sigslot is here to fulfil this need!
Sigslot immensely removes the complexity. One simply need to register a widget with event-name and connect it to callback. It provides layering over the simple watch mechanism. It is also the base class for the different panels in XrViz: an interactive visualisation interface for xarray and dfviz: an interactive interface to visualise dataframes. Both these dashboards demonstrate its capabilities in construction of complex graphical user interfaces.
Martin Durant is the author of Sigslot. Here are his views:
Having previously worked with desktop applications (e.g., Anaconda Navigator), I missed a declarative, structured way to pass messages and object state between the different parts of a Panel application. XrViz and dfviz are very much like desktop applications, more so than many of the example dashboard-oriented data display examples for Panel.
Sometimes, you want more than to declare some data structure and set of value dependencies (although that is already very powerful). Also, it is important to hide the inner implementation of some part of the interface, and specify to users of that class, a public API that you would like them to use. In that way, you can change the implementation at any time without having to change the code that calls the class; but it also drastically reduces the cost the use the class, because users need know far fewer, well-documented things.
The watch callbacks are the lowest level and therefore most versatile approach to defining callbacks but it is very easy to end up with a horrible amount of complexity if you define a lot of callbacks. Various GUI toolkits have solved this in different ways, Qt for example has a signalling API where you define a signal by name and then you can connect to those signals by name. This is a powerful way to group and keep track of callbacks and reduces the amount of complexity a user has to keep track of.
Sigslot is a similar mechanism.
The following code will print the updated value in console however you can easily replace it with the function that you desire.
It allows us to easily associate an arbitrary number of callbacks with an event, in a known order, and declare these events to other classes rather than them having to dive into the widget and value names hidden in the implementation. It also comes with further benefits like being able to ignore events and logging. We only declare those signals which we want to expose as an external API and now one can easily change the internal widgets that make this event.
My experience with Sigslot
I have used Sigslot mechanism to design XrViz. Each panel in its dashboard requires complex interaction between its widgets and the other panels. Sigslot has really removed the complexity which otherwise would have been induced. It lets you focus on completing the work at hand, rather than focusing and spending time on linking the widgets, since it is explicit about declaring which events are meaningful. Also it helps keep code short, simple and clear. I can say that it automates linking of widgets with callbacks. As of now, it is not present in Panel (issue is open here). I feel it must become a part of Panel, considering the potential it has to significantly improve the experience of users in linking widgets although you can still use it even now since it is a small piece of code. XrViz is using Sigslot mechanism for all the linking. The simple watch mechanism has not been used directly anywhere in the code.