From b0b99434580a3336eb3ed2df4d6e3d6202891fa9 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 10 Jun 2026 23:20:31 +0000 Subject: [PATCH] fix: unify label widths when widgets passed to Container constructor Container(widgets=[...]) rendered with different label/control alignment than an empty Container populated with append(). During __init__, widgets are inserted before _initialized is set to True, but _unify_label_widths() is a no-op until _initialized is True, so label widths were never unified for constructor-supplied widgets. Call _unify_label_widths() once after initialization completes. Fixes #729 --- .../widgets/bases/_container_widget.py | 4 +++ tests/test_container.py | 35 +++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/src/magicgui/widgets/bases/_container_widget.py b/src/magicgui/widgets/bases/_container_widget.py index 9a2ebc31f..b958bc833 100644 --- a/src/magicgui/widgets/bases/_container_widget.py +++ b/src/magicgui/widgets/bases/_container_widget.py @@ -105,6 +105,10 @@ def __init__( self._insert_widget(index, widget) self.native_parent_changed.connect(self.reset_choices) self._initialized = True + # label widths are not unified during __init__ (because _unify_label_widths + # is a no-op until _initialized is True), so do it once now that all the + # widgets passed to the constructor have been inserted. + self._unify_label_widths() def __len__(self) -> int: """Return the count of widgets.""" diff --git a/tests/test_container.py b/tests/test_container.py index 15a85880f..038e8cbd7 100644 --- a/tests/test_container.py +++ b/tests/test_container.py @@ -58,6 +58,41 @@ def _label_width(): container.close() +def test_container_label_widths_unified_on_construction(): + """Constructor and append should produce the same label alignment. + + Regression test for https://github.com/pyapp-kit/magicgui/issues/729 + """ + + def _label_widths(container): + return [ + w._labeled_widget().label_width + for w in container + if w._labeled_widget() is not None + ] + + via_constructor = widgets.Container( + widgets=[ + widgets.LineEdit(label="Name", value="Ada"), + widgets.SpinBox(label="Very long label", value=3), + ] + ) + via_append = widgets.Container() + via_append.append(widgets.LineEdit(label="Name", value="Ada")) + via_append.append(widgets.SpinBox(label="Very long label", value=3)) + + constructor_widths = _label_widths(via_constructor) + append_widths = _label_widths(via_append) + + # all labels within a container should share the same (widest) width + assert len(set(constructor_widths)) == 1 + # and both construction methods should agree + assert constructor_widths == append_widths + + via_constructor.close() + via_append.close() + + @pytest.mark.parametrize("scrollable", [False, True]) def test_labeled_widget_container(scrollable): """Test that _LabeledWidgets follow their children."""