Integration of napari: module? subclass? plugin?

I’m currently using the napari Viewer launched from a notebook to load some data, do some annotation, grabbing the results in the notebook, doing some simple computation in the notebook and then saving the results to disk. I call this workflow HANWIIMPFT for here's a notebook with instructions in markdown, please follow them. While this is a catchy name, I would like to move to a world where the user’s actions can be guided more interactively and maybe have one less thing to open. I can think of some options, but they all seem a little weird:

  1. build a PyQt app that uses napari as a module and pops up a viewer that is controlled by the app. Any additional interaction like dialog windows or computation is done in/from the parent PyQt object.
  2. subclass the viewer. I have done this for another project and like it OK, but it’s sort of a no-no for a few reasons. First of all, it’s hard to maintain something like this at the current stage of napari development and second, @sofroniewn told me not to do it.
  3. plugins. plugins will save us all, but that conversation only really starts once the interface covers all the bases for your functionality, and even then it’s not clear how you would modify user interaction (like enforcing a series of GUI steps) or running some code that is useful for me but no one else.

So what to do? I’d like to put the work into a tool that can fit into the napari vision for the future…

2 Likes

Hi Brian, I’m sure @sofroniewn, @jni, and others will have thoughts, but here are mine:

I definitely agree that subclassing the viewer is a bad idea, and I can’t really see the benefit of it. there are a number of ways to tack on additional GUI functionality to the viewer without subclassing (more below)… but if you have something specific in mind that you feel necessitates subclassing, feel free to clarify.

plugins will hopefully eventually be able to help with something like this, but at the moment the only clearly delineated application for plugins is related to IO… whereas something like this that pops up a whole independent GUI guiding the user through some workflow is well beyond what plugins are ready for at the moment.

If you’re excited to get going on something now, that basically leaves creating some new Qt widgets that you build and add on to the napari interface, and I think that’s the way to go. Depending on what you want to do, I don’t think you necessarily need an entirely new Qt app, I would just build a QWidget that has what you need, and then integrate it into napari with viewer.window.add_dock_widget(your_widget) (see #695 for some of the original discussion/examples of that method).

To build a workflow, the first thing that comes to mind is to have a series of (widgets most of which are hidden) that are designed to accept user input as needed for a particular step, and then hide themselves and show the next widget in the pipeline (possibly adding things or updating the viewer as necessary). All of that is doable with Qt signals and slots, but admittedly requires some research.

I’ll point out a side/companion package that I’m working on called magicgui that aims to make it easier to create small widgets based on function signatures, while abstracting away the Qt part. You might consider looking at that as well. Here are napari examples for an image arithmetic widget, and a gui that wraps a parameter sweep for a scikit-image function. note, it’s an early project so can’t handle very complex cases yet.

If you’re worried about future compatibility, i would think it’s safe to say that constructing your own QWidget (or using magicgui) is likely to remain relevant for the foreseeable future.

lastly: if you want to point us to some specific examples, we might be able to provide more specific guidance.

3 Likes

thanks @talley!

I like the docked widget suggestion- It totally makes sense and I’m embarrassed that I missed that functionality in napari. I’ve played the pyqt game a bit so I should be able to manage the communication OK, but I’ll continue to post here with updates/questions.

the future compatibility concern is mostly around the blistering pace of napari development- I’m hoping to make smart choices about how to integrate with napari to keep the maintenance/updating to a dull roar. the single QWidget is at least self contained and should have pretty straightfoward interactions with the Viewer.

1 Like