Results 1 to 2 of 2

Thread: Index out of bounds in custom QLayout subclass

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Dec 2009
    Posts
    33
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Index out of bounds in custom QLayout subclass

    This is really puzzling me:
    I have a subclass of QLayout based on the flow example in the documentation. I've created a new widget that uses it, and for some reason, now Qt is trying to access itemAt with an index >= count() which is resulting in an exception. It is not calling count() before it asks for each item My code is not calling itemAt() anywhere. Here is the part of the widget class:
    Qt Code:
    1. class DElementWidget(QWidget):
    2. def __init__(self, element, *args):
    3. super(DElementWidget, self).__init__(*args)
    4. self.element = element
    5. self.view_mode = True
    6. self.format = ['title', 'name', ('string', '='), 'value']
    7.  
    8. layout = QGridLayout()
    9. layout.setSpacing(2)
    10. layout.setMargin(2)
    11.  
    12. Omitted, added 4 buttons here
    13.  
    14. layout.setColumnMinimumWidth(4, 30)
    15. layout.setColumnStretch(4, 1)
    16.  
    17. format_holder_w = QWidget()
    18.  
    19. self.format_holder = DFlowLayout(2, 3, 3)
    20. format_holder_w.setLayout(self.format_holder)
    21. for index in range(len(self.format)):
    22. w = self.widget_for(index)
    23. self.format_holder.addWidget(w)
    24.  
    25. if isinstance(self.element.value, Integer):
    26. self.format_holder.addWidget(DElementWidget(DObject(RealNumber(6)*RealNumber(7), parent=self.element)))
    27.  
    28. scrollarea = QScrollArea()
    29. scrollarea.setWidget(format_holder_w)
    30. layout.addWidget(scrollarea, 1, 0, 1, 5)
    31.  
    32. self.setLayout(layout)
    33.  
    34. def widget_for(self, index):
    35. return QLabel(unicode(self.format[index]))
    To copy to clipboard, switch view to plain text mode 
    Here are parts of the layout:
    Qt Code:
    1. class DFlowLayout(QLayout):
    2. '''Translated from http://doc.qt.nokia.com/latest/layouts-flowlayout.html'''
    3. def __init__(self, margins = -1, hspace=-1, vspace=-1, *args):
    4. super(DFlowLayout, self).__init__(*args)
    5. self.setContentsMargins(margins, margins, margins, margins)
    6. self._hspace = hspace
    7. self._vspace = vspace
    8. self.valign = Qt.AlignCenter
    9. self.halign = Qt.AlignLeft
    10. self.items = []
    11.  
    12. def addItem(self, item):
    13. print 'added', item
    14. self.items.append(item)
    15.  
    16. def replaceItem(self, old, item):
    17. ....
    18. Omitted, not used
    19. ....
    20.  
    21. def count(self):
    22. print len(self.items)
    23. return len(self.items)
    24.  
    25. def horizontalSpacing(self):
    26. if self._hspace >= 0: return self._hspace
    27. else: return self.smartSpacing(QStyle.PM_LayoutHorizontalSpacing)
    28.  
    29. def takeAt(self, index):
    30. v = self.items[index]
    31. self.items = self.items[:index] + self.items[index+1:]
    32. return v
    33.  
    34. def itemAt(self, index):
    35. print 'get', index
    36. return self.items[index]
    37.  
    38. def expandingDirections(self):
    39. return Qt.Orientation()
    40.  
    41. def setGeometry(self, rect):
    42. QLayout.setGeometry(self, rect)
    43. self.doLayout(rect)
    44.  
    45. def lines(self, width = -1):
    46. ...
    47. Omitted, returns the wrapped lines and their dimensions
    48. ....
    49. return result, widths, heights
    50.  
    51. def hasHeightForWidth(self):
    52. return True
    53.  
    54. def heightForWidth(self, width):
    55. return sum(self.lines(width - 2*self.margin())[2]) + 2*self.margin()
    56.  
    57. def sizeHint(self):
    58. return self.minimumSize()
    59.  
    60. def minimumSize(self):
    61. res = self.lines()
    62. if len(res[0]) == 0:
    63. return QSize()
    64. width = max(res[1]) + 2*self.margin()
    65. height = sum(res[2]) + 2*self.margin()
    66. #print height
    67. return QSize(width, height)
    68.  
    69. def doLayout(self, rect):
    70. .....
    71. Omitted, places lines
    72. .....
    73.  
    74. def verticalSpacing(self):
    75. if self._vspace >= 0: return self._vspace
    76. else: return self.smartSpacing(QStyle.PM_LayoutVerticalSpacing)
    77.  
    78. def smartSpacing(self, thingy):
    79. parent = self.parent()
    80. if parent == None:
    81. return None
    82. elif parent.isWidgetType():
    83. return thingy.style().pixelMetric(thingy, 0, thingy)
    84. else:
    85. return parent.spacing()
    To copy to clipboard, switch view to plain text mode 
    Adding widgets to format_holder_w but not the layout does not change which items are accessed. It always tries to get one more item than exists in the array, except when the calls are preceeded by a call to count() in which case there is no exception. This class has worked before without errors. I'm really at a loss here, WTF is going on?

  2. #2
    Join Date
    Dec 2009
    Posts
    33
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Index out of bounds in custom QLayout subclass

    I replaced my layout with a QHBoxLayout and there were no errors.

Similar Threads

  1. Replies: 6
    Last Post: 13th August 2011, 18:31
  2. Custom QLayout in .ui file
    By gcubar in forum Qt Programming
    Replies: 2
    Last Post: 14th February 2011, 13:44
  3. QGraphicsItem subclass and accessing custom properties
    By been_1990 in forum Qt Programming
    Replies: 4
    Last Post: 19th November 2010, 01:48
  4. Replies: 3
    Last Post: 10th December 2009, 22:53
  5. custom QLayout help
    By Micawber in forum Qt Programming
    Replies: 2
    Last Post: 19th October 2007, 21:44

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.