Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Best practice examples for long running computation widgets #170

Open
GenevieveBuckley opened this issue Oct 18, 2023 · 3 comments
Open

Comments

@GenevieveBuckley
Copy link
Contributor

I'd like this repository to include one or two examples of best practice widgets for long running computations, using thread workers and progress bars.

There are a few different combinations of situations we should demonstrate:

  1. blocking function, plus progress bar of known total length
  2. blocking function, plus indeterminate progress bar
  3. thread worker (non-blocking), plus progress bar of known total length
  4. thread worker (non-blocking), plus indeterminate progress bar

Re: progress bars
It's very important for users to have reassurance that the program is doing something. So important, that I think we should include this info in the demo examples, so plugin authors will be much more likely to include this wherever it's appropriate.

Re: thread workers
There are plenty of situations where plugin authors might want to start some long computation that will write the results to an output file. This is a great candidate for using a thread worker, so that users can still pan/zoom/interact with the images while the results are being computed and written to disk.

Maybe it would make the most sense to add another file, called _widget_with_progressbar.py, and a corresponding test file. Both _widget.py and _widget_with_progressbar.py should get added to the new template if the user selects "yes" when the cookiecutter asks if they want to include widgets in their plugin.

@GenevieveBuckley
Copy link
Contributor Author

GenevieveBuckley commented Oct 18, 2023

Here's an example for (4) a thread worker (non-blocking), plus indeterminate progress bar

from time import sleep
from magicgui import magic_factory
from magicgui.tqdm import tqdm


@magic_factory(
    threshold={"widget_type": "FloatSlider", "max": 20},
    call_button="Calculate!",
)
def example_magic_widget(
    img_layer: "napari.layers.Image",
    threshold: "float"
) -> "napari.types.LabelsData":
    with tqdm() as pbar:
        @thread_worker(connect={"finished": lambda: pbar.progressbar.hide()})
        def long_running():
            sleep(5)  # let's pretend we don't know how long this function is going to take

        long_running()

@Czaki
Copy link
Contributor

Czaki commented Oct 18, 2023

We may put this in documentation, but I prefer not to store this in the template itself as it may confuse manny people with multiple selections.

@lucyleeow
Copy link

+1 for adding a section in the docs!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants