Skip to content

Commit 08849f7

Browse files
committed
Simplify computed item widgets update mechanism
1 parent 2ab87c2 commit 08849f7

2 files changed

Lines changed: 38 additions & 30 deletions

File tree

guidata/dataset/qtitemwidgets.py

Lines changed: 20 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -230,40 +230,30 @@ def notify_value_change(self) -> None:
230230
if not self.build_mode:
231231
self.parent_layout.widget_value_changed()
232232

233-
def get_highest_layout(self) -> DataSetEditLayout:
234-
"""Get the highest-level layout (in case of nested groups)
233+
def retrieve_top_level_layout(self) -> DataSetEditLayout:
234+
"""Retrieve the top-level layout associated with this widget.
235+
236+
If the current widget is part of a group, this method returns the parent layout
237+
of the group widget. Otherwise, it returns the immediate parent layout.
235238
236239
Returns:
237-
Highest-level DataSetEditLayout instance
240+
DataSetEditLayout: The top-level layout for this widget.
238241
"""
239-
higher_level_layout = self.parent_layout
240-
242+
top_level_layout = self.parent_layout
241243
if self.parent_layout.group_widget is not None:
242244
# If we are in a group, we need to iterate over widgets of this group but
243245
# also over widgets of the other groups
244-
higher_level_layout = self.parent_layout.group_widget.parent_layout
245-
return higher_level_layout
246-
247-
def update_computed_items(self) -> bool:
248-
"""Update widgets for computed items when any value changes.
246+
top_level_layout = self.parent_layout.group_widget.parent_layout
247+
return top_level_layout
249248

250-
Returns:
251-
True if any computed items were updated
252-
"""
253-
updated = False
254-
higher_level_layout = self.get_highest_layout()
255-
widgets = higher_level_layout.widgets
256-
for widget in higher_level_layout.widgets:
257-
if isinstance(widget, GroupWidget):
258-
widgets += widget.edit.widgets
249+
def contains_computed_items(self) -> bool:
250+
"""Check if there are any computed items in the layout."""
251+
widgets = self.retrieve_top_level_layout().get_terminal_widgets()
259252
for widget in widgets:
260-
if widget is not self: # Don't update the widget that just changed
261-
computed_prop = widget.item.get_prop("data", "computed", None)
262-
if isinstance(computed_prop, ComputedProp):
263-
# Just trigger the widget to refresh its display
264-
widget.set_state()
265-
updated = True
266-
return updated
253+
computed_prop = widget.item.get_prop("data", "computed", None)
254+
if isinstance(computed_prop, ComputedProp):
255+
return True
256+
return False
267257

268258

269259
class GroupWidget(AbstractDataSetWidget):
@@ -425,15 +415,15 @@ def set_state(self) -> None:
425415
def _display_callback(widget: AbstractDataSetWidget, value):
426416
"""Handling of display callback"""
427417
cb = widget.item.get_prop_value("display", "callback", None)
428-
higher_level_layout = widget.get_highest_layout()
429-
if widget.update_computed_items() or cb is not None:
418+
if widget.contains_computed_items() or cb is not None:
419+
top_level_layout = widget.retrieve_top_level_layout()
430420
if widget.build_mode:
431421
widget.set()
432422
else:
433-
higher_level_layout.update_dataitems()
423+
top_level_layout.update_dataitems()
434424
if cb is not None:
435425
cb(widget.item.instance, widget.item.item, value)
436-
higher_level_layout.update_widgets(except_this_one=widget)
426+
top_level_layout.update_widgets(except_this_one=widget)
437427

438428

439429
class LineEditWidget(AbstractDataSetWidget):

guidata/dataset/qtwidgets.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,24 @@ def widget_value_changed(self) -> None:
506506
if self.change_callback is not None:
507507
self.change_callback()
508508

509+
def get_terminal_widgets(self) -> list[AbstractDataSetWidget]:
510+
"""Get all terminal widgets (i.e. not GroupWidget or TabGroupWidget).
511+
512+
Returns:
513+
List of terminal widgets
514+
"""
515+
stack = self.widgets[:]
516+
terminal_widgets = []
517+
while stack:
518+
widget = stack.pop()
519+
if isinstance(widget, GroupWidget):
520+
stack.extend(widget.edit.widgets)
521+
elif isinstance(widget, TabGroupWidget):
522+
stack.extend(widget.widgets)
523+
else:
524+
terminal_widgets.append(widget)
525+
return terminal_widgets
526+
509527

510528
from guidata.dataset.dataitems import ( # noqa: E402
511529
BoolItem,

0 commit comments

Comments
 (0)