Skip to content

Set Choices Dynamically

Choices in magicgui

Some magicgui widgets, such as ComboBox and Select, support "choices" option. This option not only accept static choices like choices=["a", "b", "c"] but choices that can be dynamically changed are also supported by giving a choice-getter function.

from magicgui.widgets import ComboBox
import random

def _get_choices(widget=None):
    # prepare choices randomly.
    return random.choices([1, 2, 3, 4], k=2)

wdt = ComboBox(choices=_get_choices)

In the example above, choices of the ComboBox widget are defined by the _get_choices function and will be resampled when reset_choices is called.

If you want to create FunctionGui with dynamic choices, your code will look like this.

from magicgui import magicgui

@magicgui(a={"choices": _get_choices})
def func(a):
    """do something"""

To resample choices, you only have to call the reset_choices method on the parent widget.

func.reset_choices()

Use Methods

Similar to the "bind" option, you can set method defined in a magic-class to "choices" option (See Binding Values to Arguments). Magic-class will call it as an instance method every time choices need resetting. A choices option should be set using set_options wrapper as usual.

Following example is a simple file explorer made of magicclass. Since you have to reset choices every time current directory is changed, the "chocies" options is very important.

import os
from magicclass import magicclass, set_options

RETURN = "../"

@magicclass
class Main:
    def __init__(self):
        self._cd = os.getcwd()  # get current directory

    def _get_files(self, w=None):
        return os.listdir(self._cd) + [RETURN]

    @set_options(f={"choices": _get_files})
    def set_directory(self, f: str):
        if f == RETURN:
            self._cd = os.path.dirname(self._cd)  # move back to the parent directory
        else:
            self._cd = os.path.join(self._cd, f)  # go to new directory
        self.reset_choices()

    def show_current_directory(self):
        print(self._cd)

Choices in MagicField

Unlike the "bind" option, "choices" option is sometimes useful in fields. Methods defined in a magic class can also be used in field objects.

Following example is a file explorer similar to the previous one but defined using fields.

import os
from magicclass import magicclass, set_options, field
from magicgui.widgets import RadioButtons

RETURN = "../"

@magicclass
class Main:
    def _get_files(self, w=None):
        return os.listdir(self.cd.value) + [RETURN]

    cd = field(os.getcwd(), enabled=False)
    files = field(RadioButtons, options={"choices": _get_files})

    def goto(self):
        f = self.files.value
        if f == RETURN:
            self.cd.value = os.path.dirname(self.cd.value)  # move back to the parent directory
        else:
            self.cd.value = os.path.join(self.cd.value, f)  # go to new directory
        self.reset_choices()