migration guide#
v0.3.0 migration guide#
October, 2021
Version 0.3.0 of magicgui introduced some changes to the events and callbacks API. See https://github.com/pyapp-kit/magicgui/pull/253 for details
Callbacks now receive the value directly, instead of an Event
object#
magicgui 0.3.0 is now using psygnal as its event/callback handler.
Callbacks connected to widget.changed
(and other event emitters) may now receive the
value(s) directly, instead of an event object:
@widget.changed.connect
def my_callback(event):
# event was an `Event` object with a `value` attribute
new_value = event.value
Existing code using callbacks with a single positional argument will continue to receive a single Event object (and a warning will be shown, until v0.4.0 where it will become an error).
To silence the warning and opt in to the new pattern of receiving value directly, you can do one of two things:
- type hint your single positional argument as anything other than
magicgui.events.Event
- provide a callback that takes no arguments
@widget.changed.connect
def my_callback(new_value: int):
... # use new_value directly
# or, if you don't need to use new_value
@widget.changed.connect
def my_callback():
# something that didn't need the value
...
Event emitters take no keyword arguments#
For the few packages who were manually emitting change events,
you should no longer provide the value=
keyword when emitting.
widget.changed(value='whatever')
widget.changed.emit('whatever')
# OR (if you prefer the direct __call__ syntax)
widget.changed('whatever')
v0.2.0 migration guide#
December, 2020
Version 0.2.0 of magicgui was a complete rewrite that introduced a couple breaking API changes
.Gui()
attribute removed#
Before v0.2.0
, the magicgui.magicgui
decorator added a Gui
attribute to
the decorated function that was to be called to instantiate a widget. In v0.2.0
the object returned from the magicgui.magicgui
decorator is already an
instantiated magicgui.widgets.Widget
.
from magicgui import magicgui, event_loop
@magicgui
def function(x, y):
...
with event_loop():
gui = function.Gui(show=True)
from magicgui import magicgui
@magicgui
def function(x, y):
...
function.show(run=True)
New base widget type#
Before v0.2.0
, the Gui()
object returned by the magicgui.magicgui
decorator was a MagicGuiBase
widget class, which in turn was a direct
subclass of a backend widget, such as a
QtWidgets.QWidget
. In v0.2.0
, all
widgets derive from [magicgui.widgets.Widget``][magicgui.widgets.Widget],
and the *backend* is available at
widget.native. If you are incorporating
magicgui widgets into a larger Qt-based GUI, please note that you will want
to use
widget.nativeinstead of
widget`
from magicgui import magicgui, use_app
use_app('qt')
@magicgui
def function(x, y):
...
>>> print(type(function))
<class 'magicgui.widgets.FunctionGui'>
>>> print(type(function.native))
<class 'PyQt5.QtWidgets.QWidget'>
Starting the application#
It is now easier to show a widget and start an application by calling
widget.show(run=True)
. Calling show(run=True)
will immediately block
execution of your script and show the widget. If you wanted to (for instance)
show multiple widgets next to each other, then you would still want to use the
event_loop
context manager:
from magicgui import magicgui, event_loop
@magicgui
def function_a(x=1, y=3):
...
@magicgui
def function_b(z='asdf'):
...
with event_loop():
function_a.show()
function_b.show()
# both widgets will show (though b may be on top of a)
Getting and setting values#
To get or set the value of a widget programmatically, you no
longer set the corresponding widget attribute directly, but rather
use the widget.value
attribute:
Old Method 👎
gui.x
used to be a
descriptor object
to get/set the value, but the actual underlying widget was at gui.x_widget
gui = function.Gui()
gui.x = 10
New Method 👍
now function.x
IS the widget, and you set its value with
function.x.value
function.x.value = 10
Connecting callbacks to events#
When binding callbacks to change events, you no longer connect to
gui.<name>_changed
, you now connect to function.<name>.changed
:
gui = function.Gui()
gui.x_changed.connect(my_callback)
function.x.changed.connect(my_callback)
Renamed#
-
Widget.refresh_choices
has been renamed toWidget.reset_choices
. -
@magicgui(result=True)
has been renamed to@magicgui(result_widget=True)