Source code for trspectrometer.qtwidgets

import os

from PySide6 import QtCore, QtWidgets
from PySide6.QtCore import Qt

[docs] class FlowLayout(QtWidgets.QLayout): """ A ``QLayout`` which arranges its child widgets horizontally and vertically. A Qt for Python port of the `layouts/flowlayout <https://doc.qt.io/qt-5/qtwidgets-layouts-flowlayout-example.html>`_ example. If enough horizontal space is available, it looks like an ``HBoxLayout``, but if space is lacking, it automatically wraps its children into multiple rows. """ heightChanged = QtCore.Signal(int) def __init__(self, parent=None, margin=0, spacing=-1): super().__init__(parent) if parent is not None: self.setContentsMargins(margin, margin, margin, margin) self.setSpacing(spacing) self._item_list = [] def __del__(self): while self.count(): self.takeAt(0)
[docs] def addItem(self, item): # pylint: disable=invalid-name self._item_list.append(item)
[docs] def addSpacing(self, size): # pylint: disable=invalid-name self.addItem(QtWidgets.QSpacerItem(size, 0, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Minimum))
[docs] def count(self): return len(self._item_list)
[docs] def itemAt(self, index): # pylint: disable=invalid-name if 0 <= index < len(self._item_list): return self._item_list[index] return None
[docs] def takeAt(self, index): # pylint: disable=invalid-name if 0 <= index < len(self._item_list): return self._item_list.pop(index) return None
[docs] def expandingDirections(self): # pylint: disable=invalid-name,no-self-use return Qt.Orientations(Qt.Orientation(0))
[docs] def hasHeightForWidth(self): # pylint: disable=invalid-name,no-self-use return True
[docs] def heightForWidth(self, width): # pylint: disable=invalid-name height = self._do_layout(QtCore.QRect(0, 0, width, 0), True) return height
[docs] def setGeometry(self, rect): # pylint: disable=invalid-name super().setGeometry(rect) self._do_layout(rect, False)
[docs] def sizeHint(self): # pylint: disable=invalid-name return self.minimumSize()
[docs] def minimumSize(self): # pylint: disable=invalid-name size = QtCore.QSize() for item in self._item_list: minsize = item.minimumSize() extent = item.geometry().bottomRight() size = size.expandedTo(QtCore.QSize(minsize.width(), extent.y())) margin = self.contentsMargins().left() size += QtCore.QSize(2 * margin, 2 * margin) return size
def _do_layout(self, rect, test_only=False): m = self.contentsMargins() effective_rect = rect.adjusted(+m.left(), +m.top(), -m.right(), -m.bottom()) x = effective_rect.x() y = effective_rect.y() line_height = 0 for item in self._item_list: wid = item.widget() space_x = self.spacing() space_y = self.spacing() if wid is not None: space_x += wid.style().layoutSpacing( QtWidgets.QSizePolicy.PushButton, QtWidgets.QSizePolicy.PushButton, Qt.Horizontal) space_y += wid.style().layoutSpacing( QtWidgets.QSizePolicy.PushButton, QtWidgets.QSizePolicy.PushButton, Qt.Vertical) next_x = x + item.sizeHint().width() + space_x if next_x - space_x > effective_rect.right() and line_height > 0: x = effective_rect.x() y = y + line_height + space_y next_x = x + item.sizeHint().width() + space_x line_height = 0 if not test_only: item.setGeometry(QtCore.QRect(QtCore.QPoint(x, y), item.sizeHint())) x = next_x line_height = max(line_height, item.sizeHint().height()) new_height = y + line_height - rect.y() self.heightChanged.emit(new_height) return new_height
[docs] class AspectRatioPixmapLabel(QtWidgets.QLabel): """ A QLabel which maintains the correct aspect ratio of the contained image upon resize. """ def __init__(self, parent=None): super().__init__(parent=parent) self._pixmap = None self.setMinimumSize(1, 1)
[docs] def setPixmap(self, pixmap): self._pixmap = pixmap super().setPixmap(self.scaledPixmap())
[docs] def heightForWidth(self, width): if self._pixmap is None: return self.height() return self._pixmap.height()*width/self._pixmap.width()
[docs] def sizeHint(self): width = self.width() return QtCore.QSize(width, self.heightForWidth(width))
[docs] def scaledPixmap(self): return self._pixmap.scaled(QtCore.QSize(self.size()), Qt.KeepAspectRatio, Qt.SmoothTransformation)
[docs] def resizeEvent(self, event): if self._pixmap is None: return super().setPixmap(self.scaledPixmap())