Skip to content

Commit

Permalink
Merge 6126401 into aaa4eb9
Browse files Browse the repository at this point in the history
  • Loading branch information
tlambert03 committed Feb 10, 2021
2 parents aaa4eb9 + 6126401 commit e53babc
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 39 deletions.
3 changes: 2 additions & 1 deletion magicgui/backends/_qtpy/widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,8 @@ class Table(QBaseWidget, _protocols.TableWidgetProtocol):

def __init__(self):
super().__init__(QtW.QTableWidget)
self._qwidget.horizontalHeader().setSectionResizeMode(QtW.QHeaderView.Stretch)
header = self._qwidget.horizontalHeader()
header.setSectionResizeMode(QtW.QHeaderView.Stretch)
# self._qwidget.horizontalHeader().setSectionsMovable(True) # tricky!!
self._qwidget.itemChanged.connect(self._update_item_data_with_text)

Expand Down
24 changes: 23 additions & 1 deletion magicgui/signature.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ def split_annotated_type(annotation: _AnnotatedAlias) -> tuple[Any, WidgetOption
return annotation.__args__[0], meta


class _void:
"""private sentinel."""


class MagicParameter(inspect.Parameter):
"""A Parameter subclass that is closely linked to a magicgui.Widget object.
Expand Down Expand Up @@ -223,10 +227,28 @@ def to_container(self, **kwargs) -> Container:

return Container(
widgets=list(self.widgets(kwargs.get("app")).values()),
return_annotation=self.return_annotation,
**kwargs,
)

def replace(
self,
*,
parameters=_void,
return_annotation: Any = _void,
) -> MagicSignature:
"""Create a customized copy of the Signature.
Pass ``parameters`` and/or ``return_annotation`` arguments
to override them in the new copy.
"""
if parameters is _void:
parameters = self.parameters.values()

if return_annotation is _void:
return_annotation = self.return_annotation

return type(self)(parameters, return_annotation=return_annotation)


def magic_signature(
obj: Callable, *, gui_options: dict[str, dict] = None, follow_wrapped: bool = True
Expand Down
34 changes: 2 additions & 32 deletions magicgui/widgets/_bases/container_widget.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,7 @@
from __future__ import annotations

import inspect
from typing import (
TYPE_CHECKING,
Any,
Callable,
ForwardRef,
MutableSequence,
Sequence,
overload,
)
from typing import TYPE_CHECKING, Any, Callable, MutableSequence, Sequence, overload

from magicgui.application import use_app
from magicgui.events import EventEmitter
Expand Down Expand Up @@ -59,9 +51,6 @@ class ContainerWidget(Widget, _OrientationMixin, MutableSequence[Widget]):
Whether each widget should be shown with a corresponding Label widget to the
left, by default ``True``. Note: the text for each widget defaults to
``widget.name``, but can be overriden by setting ``widget.label``.
return_annotation : type or str, optional
An optional return annotation to use when representing this container of
widgets as an :class:`inspect.Signature`, by default ``None``
"""

changed: EventEmitter
Expand All @@ -73,38 +62,19 @@ def __init__(
layout: str = "vertical",
widgets: Sequence[Widget] = (),
labels=True,
return_annotation: Any = None,
**kwargs,
):
self._list: list[Widget] = []
self._return_annotation = None
self._labels = labels
self._layout = layout
kwargs["backend_kwargs"] = {"layout": layout}
super().__init__(**kwargs)
self.changed = EventEmitter(source=self, type="changed")
self.return_annotation = return_annotation
self.extend(widgets)
self.parent_changed.connect(self.reset_choices)
self._initialized = True
self._unify_label_widths()

@property
def return_annotation(self):
"""Return annotation to use when converting to :class:`inspect.Signature`.
ForwardRefs will be resolve when setting the annotation.
"""
return self._return_annotation

@return_annotation.setter
def return_annotation(self, value):
if isinstance(value, (str, ForwardRef)):
from magicgui.type_map import _evaluate_forwardref

value = _evaluate_forwardref(value)
self._return_annotation = value

def __getattr__(self, name: str):
"""Return attribute ``name``. Will return a widget if present."""
for widget in self:
Expand Down Expand Up @@ -265,7 +235,7 @@ def __signature__(self) -> MagicSignature:
elif seen_default:
params.sort(key=lambda x: x.default is not MagicParameter.empty)
break
return MagicSignature(params, return_annotation=self.return_annotation)
return MagicSignature(params)

@classmethod
def from_signature(cls, sig: inspect.Signature, **kwargs) -> Container:
Expand Down
38 changes: 33 additions & 5 deletions magicgui/widgets/_function_gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,16 @@
from collections import deque
from contextlib import contextmanager
from types import FunctionType
from typing import TYPE_CHECKING, Any, Callable, Deque, Generic, TypeVar, cast
from typing import (
TYPE_CHECKING,
Any,
Callable,
Deque,
ForwardRef,
Generic,
TypeVar,
cast,
)

from magicgui.application import AppRef
from magicgui.events import EventEmitter
Expand Down Expand Up @@ -94,7 +103,6 @@ class FunctionGui(Container, Generic[_R]):
"""

_widget: ContainerProtocol
__signature__: MagicSignature

def __init__(
self,
Expand Down Expand Up @@ -141,15 +149,14 @@ def __init__(
)

sig = magic_signature(function, gui_options=param_options)
self.return_annotation = sig.return_annotation
super().__init__(
layout=layout,
labels=labels,
visible=visible,
widgets=list(sig.widgets(app).values()),
return_annotation=sig.return_annotation,
name=name or self._callable_name,
)

self._param_options = param_options
self.called = EventEmitter(self, type="called")
self._result_name = ""
Expand Down Expand Up @@ -203,6 +210,27 @@ def reset_call_count(self) -> None:
# """Delete a widget by integer or slice index."""
# raise AttributeError("can't delete items from a FunctionGui")

@property
def return_annotation(self):
"""Return annotation to use when converting to :class:`inspect.Signature`.
ForwardRefs will be resolve when setting the annotation.
"""
return self._return_annotation

@return_annotation.setter
def return_annotation(self, value):
if isinstance(value, (str, ForwardRef)):
from magicgui.type_map import _evaluate_forwardref

value = _evaluate_forwardref(value)
self._return_annotation = value

@property
def __signature__(self) -> MagicSignature:
"""Return a MagicSignature object representing the current state of the gui."""
return super().__signature__.replace(return_annotation=self.return_annotation)

def __call__(self, *args: Any, **kwargs: Any) -> _R:
"""Call the original function with the current parameter values from the Gui.
Expand Down Expand Up @@ -253,7 +281,7 @@ def __call__(self, *args: Any, **kwargs: Any) -> _R:
with self._result_widget.changed.blocker():
self._result_widget.value = value

return_type = self.return_annotation
return_type = sig.return_annotation
if return_type:
from magicgui.type_map import _type2callback

Expand Down

0 comments on commit e53babc

Please sign in to comment.