From 80e32aa5f98dcdfdda56d05c8bb51c473b518538 Mon Sep 17 00:00:00 2001 From: Eric Mehl Date: Thu, 19 Oct 2023 17:22:06 -0400 Subject: [PATCH] _LinkedScrollBar : Guard against recursive updates This may fix #5296 - though I haven't been able to reproduce it. The problem appears to be endless recursion of `sliderChange()`, which may have been caused by one of the two scroll bars the `LinkedScrollBar` manages emitting a change signal that then causes the other scroll bar to update, emitting a change signal... until the stack overflows. --- Changes.md | 4 +- .../SpreadsheetUI/_LinkedScrollBar.py | 38 +++++++++++++++---- 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/Changes.md b/Changes.md index f1d2b4969cb..f4b84d8b3a9 100644 --- a/Changes.md +++ b/Changes.md @@ -16,7 +16,9 @@ Improvements Fixes ----- -- Windows : Fixed a bug preventing anything except strings from being copied and pasted. +- Windows : + - Fixed a bug preventing anything except strings from being copied and pasted. + - Fixed likely cause of crash when resizing Spreadsheet column width (#5296). 1.3.5.0 (relative to 1.3.4.0) ======= diff --git a/python/GafferUI/SpreadsheetUI/_LinkedScrollBar.py b/python/GafferUI/SpreadsheetUI/_LinkedScrollBar.py index 8b32fde85e5..0b3b0fa70f6 100644 --- a/python/GafferUI/SpreadsheetUI/_LinkedScrollBar.py +++ b/python/GafferUI/SpreadsheetUI/_LinkedScrollBar.py @@ -91,23 +91,45 @@ def __init__( self, orientation, scrolledContainers, **kw ) : scrollBar.rangeChanged.connect( Gaffer.WeakMethod( self.__rangeChanged ) ) scrollBar.stepsChanged.connect( Gaffer.WeakMethod( self.__stepsChanged ) ) + self.__isUpdating = False + def __valueChanged( self, value ) : - for scrollBar in self.__scrollBars : - scrollBar.setValue( value ) + if self.__isUpdating : + return + + try : + self.__isUpdating = True + for scrollBar in self.__scrollBars : + scrollBar.setValue( value ) + finally : + self.__isUpdating = False def __rangeChanged( self, min, max ) : - for scrollBar in self.__scrollBars : - scrollBar.setRange( min, max ) + if self.__isUpdating : + return - self.setVisible( min != max ) + try : + self.__isUpdating = True + for scrollBar in self.__scrollBars : + scrollBar.setRange( min, max ) + self.setVisible( min != max ) + finally : + self.__isUpdating = False def __stepsChanged( self, page, single ) : - for scrollBar in self.__scrollBars : - scrollBar.setPageStep( page ) - scrollBar.setSingleStep( single ) + if self.__isUpdating : + return + + try : + self.__isUpdating = True + for scrollBar in self.__scrollBars : + scrollBar.setPageStep( page ) + scrollBar.setSingleStep( single ) + finally : + self.__isUpdating = False # QScrollBar provides signals for when the value and range are changed, # but not for when the page step is changed. This subclass adds the missing