Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose QScrollArea as native widget #429

Merged
merged 1 commit into from
Jul 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions magicgui/backends/_qtpy/widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ def _mgui_set_parent(self, widget: Widget):
def _mgui_get_native_widget(self) -> QtW.QWidget:
return self._qwidget

def _mgui_get_root_native_widget(self) -> QtW.QWidget:
return self._qwidget

def _mgui_get_width(self) -> int:
"""Return the current width of the widget."""
return self._qwidget.width()
Expand Down Expand Up @@ -428,7 +431,11 @@ def __init__(self, layout="vertical", scrollable: bool = False):
def _is_scrollable(self) -> bool:
return isinstance(self._qwidget, QtW.QScrollArea)

def _mgui_get_root_native_widget(self):
return self._qwidget

def _mgui_get_native_widget(self):
# Return widget with the layout set
return self._qwidget.widget() if self._is_scrollable else self._qwidget

def _mgui_get_visible(self):
Expand Down
19 changes: 18 additions & 1 deletion magicgui/widgets/_bases/widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,26 @@ def options(self) -> dict:

@property
def native(self):
"""Return native backend widget."""
"""
Return native backend widget.

Note this is the widget that contains the layout, and not any
parent widgets of this (e.g. a parent widget that is used to
enable scroll bars)
"""
return self._widget._mgui_get_native_widget()

@property
def root_native_widget(self):
"""
Return the root native backend widget.

This can be different from the ``.native`` widget if the layout
is a child of some other widget, e.g. a widget used to enable
scroll bars.
"""
return self._widget._mgui_get_root_native_widget()

@property
def enabled(self) -> bool:
"""Whether widget is enabled (editable)."""
Expand Down
4 changes: 4 additions & 0 deletions magicgui/widgets/_protocols.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ def _mgui_set_parent(self, widget: Widget) -> None:
def _mgui_get_native_widget(self) -> Any:
raise NotImplementedError()

@abstractmethod
def _mgui_get_root_native_widget(self) -> Any:
raise NotImplementedError()

@abstractmethod
def _mgui_bind_parent_change_callback(
self, callback: Callable[[Any], None]
Expand Down
8 changes: 6 additions & 2 deletions tests/test_magicgui.py
Original file line number Diff line number Diff line change
Expand Up @@ -812,9 +812,13 @@ def test_scrollable():
def test_scrollable(a: int = 1, y: str = "a"):
...

assert test_scrollable.native is not test_scrollable.root_native_widget
assert not isinstance(test_scrollable.native, QScrollArea)
assert isinstance(test_scrollable.root_native_widget, QScrollArea)

@magicgui(scrollable=False)
def test_nonscrollable(a: int = 1, y: str = "a"):
...

assert isinstance(test_scrollable.native.parent().parent(), QScrollArea)
assert not test_nonscrollable.native.parent()
assert test_nonscrollable.native is test_nonscrollable.root_native_widget
assert not isinstance(test_nonscrollable.native, QScrollArea)
1 change: 1 addition & 0 deletions tests/test_widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ def _mgui_set_enabled(self, enabled): ... # noqa
def _mgui_get_parent(self): ... # noqa
def _mgui_set_parent(self, widget): ... # noqa
def _mgui_get_native_widget(self): return MagicMock() # noqa
def _mgui_get_root_native_widget(self): ... # noqa
def _mgui_bind_parent_change_callback(self, callback): ... # noqa
def _mgui_render(self): ... # noqa
def _mgui_get_width(self): ... # noqa
Expand Down