|
19 | 19 | EXPAND_ICON = ':/qtutils/fugue/toggle-small-expand'
|
20 | 20 | CONTRACT_ICON = ':/qtutils/fugue/toggle-small'
|
21 | 21 |
|
| 22 | +_ENABLE_LAYOUT_EVENT_TYPE = QEvent.User |
| 23 | + |
22 | 24 | class ToolPaletteGroup(QVBoxLayout):
|
23 | 25 |
|
24 | 26 | def __init__(self,*args,**kwargs):
|
@@ -265,6 +267,10 @@ def __init__(self,parent,name,*args,**kwargs):
|
265 | 267 | self._column_count = 0
|
266 | 268 | self._row_count = 0
|
267 | 269 |
|
| 270 | + # Variable for controlling whether or not self._layout_widgets() is |
| 271 | + # called in self.resizeEvent(). |
| 272 | + self._layout_widgets_during_resizeEvent = True |
| 273 | + |
268 | 274 | def addWidget(self,widget,force_relayout=True):
|
269 | 275 | # Append to end of tool pallete
|
270 | 276 | #widget.clicked.connect(embed)
|
@@ -385,24 +391,53 @@ def minimumSizeHint(self):
|
385 | 391 | height = self.minimumSize().height()
|
386 | 392 | return QSize(width, height)
|
387 | 393 |
|
| 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 | + |
388 | 406 | def resizeEvent(self, event):
|
389 | 407 | # 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)) |
406 | 441 |
|
407 | 442 |
|
408 | 443 | # A simple test!
|
|
0 commit comments