Best Practice
Here's some tips that will be useful for better GUI design.
Shared Input Parameters
If you want to control input parameters outside each magicgui
widget, the example
below is the most naive implementation.
from magicclass import magicclass, magicmenu, field, abstractapi, set_design
@magicclass
class Main:
@magicmenu
class Menu:
add = abstractapi()
sub = abstractapi()
a = field(float)
b = field(float)
result = field(float, record=False)
@set_design(location=Menu)
def add(self):
"""Add two values"""
self.result.value = self.a.value + self.b.value
@set_design(location=Menu)
def sub(self):
"""Subtract two values"""
self.result.value = self.a.value - self.b.value
However, after you calculated "4.0 + 2.0" and "6.0 - 3.0", macro will be recorded like
ui.a.value = 4.0
ui.b.value = 2.0
ui.add()
ui.a.value = 6.0
ui.b.value = 3.0
ui.sub()
This is perfectly reproducible but is not user friendly. If users want to run functions
programmatically, they'll prefer styles like add(1, 2)
. Unfriendliness is more obvious
when you changed the values of a
and b
alternately many times before adding them and
saw its macro recorded like
macro
ui.a.value = 3.0
ui.b.value = 1.0
ui.a.value = 6.0
ui.b.value = 2.0
ui.a.value = 9.0
ui.b.value = 3.0
ui.add()
To avoid this, you can use the "bind" option.
from typing import Annotated
from magicclass import magicclass, magicmenu, field
@magicclass
class Main:
@magicmenu
class Menu:
add = abstractapi()
sub = abstractapi()
a = field(float, record=False) # <- don't record
b = field(float, record=False) # <- don't record
result = field(float, record=False)
@set_design(location=Menu)
def add(self, a: Annotated[float, {"bind": a}], b: Annotated[float, {"bind": b}]):
"""Add two values"""
self.result.value = a + b
@set_design(location=Menu)
def sub(self, a: Annotated[float, {"bind": a}], b: Annotated[float, {"bind": b}]):
"""Subtract two values"""
self.result.value = a - b
Widget created by this code works completely identical to the previous one. Also, macro will be recorded in a better way.
macro
ui.add(a=4.0, b=2.0)
ui.sub(a=6.0, b=3.0)