| | |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | from PySide.QtCore import * |
| | from PySide.QtGui import * |
| |
|
| |
|
| | class FlowLayout(QLayout): |
| | widthChanged = Signal(int) |
| |
|
| | def __init__(self, parent=None, margin=0, spacing=-1, orientation=Qt.Horizontal): |
| | super(FlowLayout, self).__init__(parent) |
| |
|
| | if parent is not None: |
| | self.setContentsMargins(margin, margin, margin, margin) |
| |
|
| | self.setSpacing(spacing) |
| | self.itemList = [] |
| | self.orientation = orientation |
| |
|
| | def __del__(self): |
| | item = self.takeAt(0) |
| | while item: |
| | item = self.takeAt(0) |
| |
|
| | def addItem(self, item): |
| | self.itemList.append(item) |
| |
|
| | def count(self): |
| | return len(self.itemList) |
| |
|
| | def itemAt(self, index): |
| | if index >= 0 and index < len(self.itemList): |
| | return self.itemList[index] |
| |
|
| | return None |
| |
|
| | def takeAt(self, index): |
| | if index >= 0 and index < len(self.itemList): |
| | return self.itemList.pop(index) |
| |
|
| | return None |
| |
|
| | def expandingDirections(self): |
| | return Qt.Orientations(Qt.Orientation(0)) |
| |
|
| | def hasHeightForWidth(self): |
| | return True |
| |
|
| | def heightForWidth(self, width): |
| | if self.orientation == Qt.Horizontal: |
| | return self.doLayoutHorizontal(QRect(0, 0, width, 0), True) |
| | elif self.orientation == Qt.Vertical: |
| | return self.doLayoutVertical(QRect(0, 0, width, 0), True) |
| |
|
| | def setGeometry(self, rect): |
| | super(FlowLayout, self).setGeometry(rect) |
| | if self.orientation == Qt.Horizontal: |
| | self.doLayoutHorizontal(rect, False) |
| | elif self.orientation == Qt.Vertical: |
| | self.doLayoutVertical(rect, False) |
| |
|
| | def sizeHint(self): |
| | return self.minimumSize() |
| |
|
| | def minimumSize(self): |
| | size = QSize() |
| |
|
| | for item in self.itemList: |
| | size = size.expandedTo(item.minimumSize()) |
| |
|
| | margin, _, _, _ = self.getContentsMargins() |
| |
|
| | size += QSize(2 * margin, 2 * margin) |
| | return size |
| |
|
| | def doLayoutHorizontal(self, rect, testOnly): |
| | |
| | x = rect.x() |
| | y = rect.y() |
| | lineHeight = 0 |
| | i = 0 |
| | for item in self.itemList: |
| | wid = item.widget() |
| | |
| | spaceX = self.spacing() + wid.style().layoutSpacing( |
| | QSizePolicy.PushButton, QSizePolicy.PushButton, Qt.Horizontal |
| | ) |
| | spaceY = self.spacing() + wid.style().layoutSpacing( |
| | QSizePolicy.PushButton, QSizePolicy.PushButton, Qt.Vertical |
| | ) |
| | |
| | |
| | nextX = x + item.sizeHint().width() + spaceX |
| | |
| | if nextX - spaceX > rect.right() and lineHeight > 0: |
| | x = rect.x() |
| | y = y + lineHeight + spaceY |
| | nextX = ( |
| | x + item.sizeHint().width() + spaceX |
| | ) |
| | lineHeight = 0 |
| |
|
| | if not testOnly: |
| | item.setGeometry(QRect(QPoint(x, y), item.sizeHint())) |
| |
|
| | x = nextX |
| | lineHeight = max(lineHeight, item.sizeHint().height()) |
| | i = i + 1 |
| |
|
| | return y + lineHeight - rect.y() |
| |
|
| | def doLayoutVertical(self, rect, testOnly): |
| | |
| | x = rect.x() |
| | y = rect.y() |
| | |
| | columnWidth = 0 |
| | lineHeight = 0 |
| |
|
| | |
| | spaceX = 0 |
| | spaceY = 0 |
| |
|
| | |
| | i = 0 |
| | j = 0 |
| | for item in self.itemList: |
| | wid = item.widget() |
| | |
| | spaceX = self.spacing() + wid.style().layoutSpacing( |
| | QSizePolicy.PushButton, QSizePolicy.PushButton, Qt.Horizontal |
| | ) |
| | spaceY = self.spacing() + wid.style().layoutSpacing( |
| | QSizePolicy.PushButton, QSizePolicy.PushButton, Qt.Vertical |
| | ) |
| | |
| | |
| | nextY = y + item.sizeHint().height() + spaceY |
| | |
| | if nextY - spaceY > rect.bottom() and columnWidth > 0: |
| | y = rect.y() |
| | x = x + columnWidth + spaceX |
| | nextY = ( |
| | y + item.sizeHint().height() + spaceY |
| | ) |
| | |
| | columnWidth = 0 |
| |
|
| | |
| | j += 1 |
| | i = 0 |
| |
|
| | |
| | item.x_index = i |
| | item.y_index = j |
| |
|
| | |
| | |
| | if not testOnly: |
| | item.setGeometry(QRect(QPoint(x, y), item.sizeHint())) |
| |
|
| | y = nextY |
| | columnWidth = max( |
| | columnWidth, item.sizeHint().width() |
| | ) |
| | lineHeight = max(lineHeight, item.sizeHint().height()) |
| |
|
| | i += 1 |
| |
|
| | |
| | |
| | if not testOnly: |
| | self.calculateMaxWidth(i) |
| | self.widthChanged.emit(self.totalMaxWidth + spaceX * self.itemsOnWidestRow) |
| | return lineHeight |
| |
|
| | |
| | |
| | def calculateMaxWidth(self, numberOfRows): |
| | |
| | self.totalMaxWidth = 0 |
| | self.itemsOnWidestRow = 0 |
| |
|
| | |
| | |
| | |
| | for i in range(numberOfRows): |
| | rowWidth = 0 |
| | itemsOnWidestRow = 0 |
| | for item in self.itemList: |
| | |
| | if item.x_index == i: |
| | rowWidth += item.sizeHint().width() |
| | itemsOnWidestRow += 1 |
| | if rowWidth > self.totalMaxWidth: |
| | self.totalMaxWidth = rowWidth |
| | self.itemsOnWidestRow = itemsOnWidestRow |
| |
|