Quick Start¶
In magicgui
, you can convert functions into widgets. For instance,
from magicgui import magicgui
@magicgui
def print_text(text: str):
print(text)
print_text.show()
will create a widget that is composed of a line edit (for the input argument text
) and a
call button.
Similarly, with magicclass
decorator, you can convert a Python class into a magicgui
's
Container
widget and its methods appear as push buttons. When a button is clicked, the
corresponding magicgui will be popped up.
from magicclass import magicclass
@magicclass
class MyClass:
def set_value(self, value: str):
self.value = value
def print_value(self):
print(self.value)
ui = MyClass()
ui.show()

Note
Methods whose names start with "_" are considered as inner functions so that they will not be converted into widgets.
Use Other Widgets in magic-class¶
Magic classes can also detect other magicgui
's widgets.
from magicgui.widgets import LineEdit, Slider
from magicclass import magicclass
@magicclass
class MyClass:
s = LineEdit(label="Name:")
i = Slider(label="Age:", max=100)
def print(self):
print(f"{self.s.value} ({self.i.value})")
ui = MyClass()
ui.show()

Note
I highly recommend using field
function to create widgets in magic classes.
See Use Fields in magic-class.
If a method is decorated with @magicgui
, it will directly added in the container widget,
in place of a push button. This is natural because decorated methods are no longer functions,
but FunctionGui
widgets.
from magicgui import magicgui
from magicclass import magicclass
@magicclass
class MyClass:
@magicgui
def input_parameters(self, s: str, i: int):
self.s = s
self.i = i
def print(self):
print(f"{self.s} ({self.i})")
ui = MyClass()
ui.show()

Macro Recording¶
Another outstanding feature of magic class is its macro recorder functionalities. Function calls and value changes in child widgets are all recorded and you can generate executable Python script at any time.
Recorded macro is stored in the macro
attribute. You can generate Python script as
string just by passing it to str
.
macro_string = str(ui.macro)
print(macro_string)
A macro editor widget is always tagged at macro.widget
. It is a magicgui
widget
so you can open it by show()
method or directly append it to GUI.
ui.macro.widget.show() # show widget as a separate window.
ui.append(ui.macro.widget) # append macro as a child widget.
By default, the script shown in the macro editor is synchronized, that is, automatically updated whenever macro itself is updated.
Occasionally, you may want some functions not to record macro (such as a function that
only shows a help window). You can prevent macro recording with do_not_record
decorator.
from magicclass import magicclass, do_not_record
@magicclass
class Main:
@do_not_record
def f(self):
"""this function will never be recorded"""
ui = Main()
ui.show()
Make Document of Your Widgets Automatically¶
It is usually time consuming to make a help menu of a widget all the way. You also have to keep it updated whenever UI changed.
Magic class has a powerful help widget builder. You can create a help widget using build_help
function. The widget has a website-like layout and many information such as tooltips of widgets
and parameter annotations of functions are summerized with rich texts.
from magicclass import magicclass, build_help
@magicclass
class Main:
# many functions and widgets here.
...
help = build_help(self) # build_help returns a Widget object
help.show() # show widget

Parameter Options¶
In magicgui
you can define parameter options with keyword arguments:
@magicgui(a={"widget_type": "Slider", "step": 10})
def f(a: int): ...
However, magic classes need another way to do this because magicgui
will never be called by users.
magicclass
uses set_options
decorator instead.
from magicclass import magicclass, set_options
@magicclass
class Main:
@set_options(a={"widget_type": "Slider", "step": 10})
def f(self, a: int): ...
ui = Main()
ui.show()

Code Completion¶
A problem of using decorators to overwrite classes is code completion. When you are coding, the classes
do not inherits magic classes yet, so IDE and console don't know they will have attributes such as
self.parent_viewer
or self.name
.
All the magic classes inherits MagicTemplate
class. This class is designed in a way which does not
interfere with magic class decorators, while provides enough information of typings and annotations.
from magicclass import magicclass, MagicTemplate
@magicclass
class MyClass(MagicTemplate): # inherit here
...