Code Monkey home page Code Monkey logo

Comments (1)

tlambert03 avatar tlambert03 commented on July 18, 2024 1

the thing that makes this a bit tricky in my mind (and which makes me slightly hesitant to offer it as a feature) is the problem of the "scope" of the uniqueness. For example, in affinder, the goal is simple enough if you consider a single affinder widget (which has two comboboxes) in a single napari viewer... but what if you dropped in another affinder widget? i would assume those options only need to be unique within a given affinder widget instance, within a single viewer.

Offering unique options means having a set of all possible options, and then narrowing based on some awareness of the other widgets that are also monitoring that set of options... and that's the bit that seems like it would have a number of very valid permutations, and which i'd rather not be in the business of managing.

here's a very rough, currently broken sketch:

from typing import NewType

from magicgui import magicgui, register_type

import napari
import napari.layers
from napari.utils._magicgui import find_viewer_ancestor


def get_unique_shapes(gui):
    if not gui.parent or (viewer := find_viewer_ancestor(gui)) is None:
        return []

    # get all available layer options
    all_shapes = (
        layer
        for layer in viewer.layers
        if isinstance(layer, napari.layers.Shapes)
    )

    # get values claimed by other widgets
    # this is an ugly hack to figure out the other magicgui widgets in the same widget
    # it uses both the Qt and magicgui APIs... look into a better way
    other_values = {
        w._magic_widget.value
        for w in gui.parent.parent().children()
        if hasattr(w, '_magic_widget')
        and w._magic_widget is not gui
    }

    # return all options that are not claimed by other widgets
    return [layer for layer in all_shapes if layer not in other_values]


UniqueShapes = NewType('UniqueShapes', napari.layers.Shapes)
register_type(UniqueShapes, choices=get_unique_shapes)


@magicgui
def widget(layer1: UniqueShapes, layer2: UniqueShapes):
    ...


viewer = napari.Viewer()
viewer.window.add_dock_widget(widget)
viewer.layers.events.inserted.connect(widget.reset_choices)
viewer.layers.events.removed.connect(widget.reset_choices)
# need something like this too, but it's causing recursion errors at the moment
widget.layer1.changed.connect(widget.layer2.reset_choices)
widget.layer2.changed.connect(widget.layer1.reset_choices)
napari.run()

I say currently broken because there's a still a recursion error when you try to update the options in the other widgets whenever one of the widgets changes its value.

Anyway, that gives you a sense for how it could be done, and also how many tricky gotchas there might be in a successful implementation

from magicgui.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.