Skip to content

Commit d9eb80f

Browse files
committed
Fixed #27; worked around bug where ToolPalette.resizeEvent() could trigger itself in an infinite resursion loop.
1 parent f0999f5 commit d9eb80f

File tree

1 file changed

+51
-7
lines changed

1 file changed

+51
-7
lines changed

labscript_utils/qtwidgets/toolpalette.py

Lines changed: 51 additions & 7 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,6 +391,18 @@ 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!
390408
# print '--------- %s'%self._name
@@ -396,13 +414,39 @@ def resizeEvent(self, event):
396414
# print self.minimumSize()
397415
# print self.sizeHint()
398416
# 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()
417+
# This method can end up undergoing infinite recursion for some window
418+
# layouts, see
419+
# https://github.com/labscript-suite/labscript-utils/issues/27. It seems
420+
# that sometimes self._layout_widgets() increases the number of columns,
421+
# which then triggers a resizeEvent, which then calls
422+
# self._layout_widgets() which then decreases the number of columns to
423+
# its previous value, which triggers a resizeEvent, and so on. That loop
424+
# may occur e.g. if increasing/decreasing the number of columns
425+
# add/removes a scrollbar, which then changes the number of widgets that
426+
# can fit in a row. Keeping track of the recursion depth isn't trivial
427+
# because _layout_widgets() doesn't directly call itself; it just causes
428+
# more resizing events to be added to the event queue. To work around
429+
# that, this method will mark that future calls to this method shouldn't
430+
# call _layout_widgets() but will also add an event to the event queue
431+
# to reenable calling _layout_widgets() again once all of the resize
432+
# events caused by this call to it have been processed.
433+
434+
try:
435+
#pass resize event on to qwidget
436+
QWidget.resizeEvent(self, event)
437+
size = event.size()
438+
if size.width() == self.size().width() and size.height() == self.size().height():
439+
if self._layout_widgets_during_resizeEvent:
440+
# Avoid calling this again until all the resize events that
441+
# will be put in the queue by self._layout_widgets() have
442+
# run.
443+
self._layout_widgets_during_resizeEvent = False
444+
self._layout_widgets()
445+
finally:
446+
# Add event to end of the event queue to allow _layout_widgets() in
447+
# future calls. This event shouldn't be handled until the resize
448+
# events generated during _layout_widgets() have run.
449+
QCoreApplication.instance().postEvent(self, QEvent(_ENABLE_LAYOUT_EVENT_TYPE))
406450

407451

408452
# 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