Skip to content

Commit e74472c

Browse files
Merge pull request labscript-suite#76 from zakv/fix-27
Work around infinite recursion in ToolPalette.resizeEvent()
2 parents f0999f5 + c543328 commit e74472c

File tree

1 file changed

+51
-16
lines changed

1 file changed

+51
-16
lines changed

labscript_utils/qtwidgets/toolpalette.py

Lines changed: 51 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
EXPAND_ICON = ':/qtutils/fugue/toggle-small-expand'
2020
CONTRACT_ICON = ':/qtutils/fugue/toggle-small'
2121

22+
_ENABLE_LAYOUT_EVENT_TYPE = QEvent.User
23+
2224
class ToolPaletteGroup(QVBoxLayout):
2325

2426
def __init__(self,*args,**kwargs):
@@ -265,6 +267,10 @@ def __init__(self,parent,name,*args,**kwargs):
265267
self._column_count = 0
266268
self._row_count = 0
267269

270+
# Variable for controlling whether or not self._layout_widgets() is
271+
# called in self.resizeEvent().
272+
self._layout_widgets_during_resizeEvent = True
273+
268274
def addWidget(self,widget,force_relayout=True):
269275
# Append to end of tool pallete
270276
#widget.clicked.connect(embed)
@@ -385,24 +391,53 @@ def minimumSizeHint(self):
385391
height = self.minimumSize().height()
386392
return QSize(width, height)
387393

394+
def event(self, event):
395+
# Handle the custom event for reenabling the call to
396+
# self._layout_widgets() during self.resizeEvent().
397+
if (event.type() == _ENABLE_LAYOUT_EVENT_TYPE):
398+
self._layout_widgets_during_resizeEvent = True
399+
# Return True so that this event isn't sent along to other event
400+
# handlers as well.
401+
return True
402+
403+
# Handle all other events in the usual way.
404+
return super().event(event)
405+
388406
def resizeEvent(self, event):
389407
# overwrite the resize event!
390-
# print '--------- %s'%self._name
391-
# print self._widget_list[0].size()
392-
# print self._widget_list[0].sizeHint()
393-
# print self._widget_list[0].minimumSizeHint()
394-
# print self._layout.rowMinimumHeight(0)
395-
# print self.size()
396-
# print self.minimumSize()
397-
# print self.sizeHint()
398-
# print self.minimumSizeHint()
399-
#pass resize event on to qwidget
400-
# call layout()
401-
QWidget.resizeEvent(self, event)
402-
size = event.size()
403-
if size.width() == self.size().width() and size.height() == self.size().height():
404-
# print 'relaying out widgets'
405-
self._layout_widgets()
408+
# This method can end up undergoing infinite recursion for some window
409+
# layouts, see
410+
# https://github.com/labscript-suite/labscript-utils/issues/27. It seems
411+
# that sometimes self._layout_widgets() increases the number of columns,
412+
# which then triggers a resizeEvent, which then calls
413+
# self._layout_widgets() which then decreases the number of columns to
414+
# its previous value, which triggers a resizeEvent, and so on. That loop
415+
# may occur e.g. if increasing/decreasing the number of columns
416+
# add/removes a scrollbar, which then changes the number of widgets that
417+
# can fit in a row. Keeping track of the recursion depth isn't trivial
418+
# because _layout_widgets() doesn't directly call itself; it just causes
419+
# more resizing events to be added to the event queue. To work around
420+
# that, this method will mark that future calls to this method shouldn't
421+
# call _layout_widgets() but will also add an event to the event queue
422+
# to reenable calling _layout_widgets() again once all of the resize
423+
# events caused by this call to it have been processed.
424+
425+
try:
426+
#pass resize event on to qwidget
427+
QWidget.resizeEvent(self, event)
428+
size = event.size()
429+
if size.width() == self.size().width() and size.height() == self.size().height():
430+
if self._layout_widgets_during_resizeEvent:
431+
# Avoid calling this again until all the resize events that
432+
# will be put in the queue by self._layout_widgets() have
433+
# run.
434+
self._layout_widgets_during_resizeEvent = False
435+
self._layout_widgets()
436+
finally:
437+
# Add event to end of the event queue to allow _layout_widgets() in
438+
# future calls. This event shouldn't be handled until the resize
439+
# events generated during _layout_widgets() have run.
440+
QCoreApplication.instance().postEvent(self, QEvent(_ENABLE_LAYOUT_EVENT_TYPE))
406441

407442

408443
# A simple test!

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy