Source code for als.ui.widgets

"""
Our custom widgets
"""
import logging
import typing

from PyQt5 import QtGui
from PyQt5.QtCore import QPoint, Qt
from PyQt5.QtGui import QPainter, QPen
from PyQt5.QtWidgets import QSlider, QGraphicsView, QWidget

from als.code_utilities import log
from als.model.data import DYNAMIC_DATA

_LOGGER = logging.getLogger(__name__)


[docs]class Slider(QSlider): """ A slider that has a default value and resets to it when double-clicked """ MAX_VALUE = 255 @log def __init__(self, parent=None): super().__init__(parent) self._default_value = 0
[docs] @log def set_default_value(self, default_value): """ Sets the slider default value :param default_value: the default value :type default_value: int """ self._default_value = default_value
# pylint: disable=C0103
[docs] @log def mouseDoubleClickEvent(self, _): """ User double-clicked the slider :param _: ignored Qt event """ self.setValue(self._default_value)
[docs]class ImageView(QGraphicsView): """ The main image view. Subclasses QGraphicsView to add mousewheel zoom features """ _ZOOM_FACTOR = 1.1 @log def __init__(self, parent: typing.Optional[QWidget] = ...): super().__init__(parent) self.setDragMode(QGraphicsView.ScrollHandDrag) self.setTransformationAnchor(QGraphicsView.AnchorUnderMouse) # pylint: disable=C0103
[docs] @log def wheelEvent(self, event: QtGui.QWheelEvent) -> None: """ Performs zoom in & out according to mousewheel moves :param event: The Qt wheel event :type event: QtGui.QWheelEvent """ if event.angleDelta().y() > 0: self.scale(ImageView._ZOOM_FACTOR, ImageView._ZOOM_FACTOR) elif event.angleDelta().y() < 0: self.scale(1 / ImageView._ZOOM_FACTOR, 1 / ImageView._ZOOM_FACTOR)
# pylint: disable=C0103
[docs] @log def mouseDoubleClickEvent(self, _): """ Reacts to a double-click in image view : Fit image in view :param _: ignored Qt event """ self.fitInView(self.scene().items()[0], Qt.KeepAspectRatio)
[docs]class HistogramView(QWidget): """ Our main histogram display """ _TOP_MARGIN_IN_PX = 5 @log def __init__(self, parent=None): QWidget.__init__(self, parent) self._painter = QPainter() self._color_pens = [QPen(Qt.red), QPen(Qt.green), QPen(Qt.blue)] for pen in self._color_pens: pen.setWidth(2) self._white_pen = QPen(Qt.white) self._white_pen.setWidth(2) # pylint: disable=C0103, R0914
[docs] @log def paintEvent(self, _): """ Do the painting, Leonardo ! :param _: ignored Qt event """ if self.isVisible(): self._painter.begin(self) self._painter.translate(QPoint(0, 0)) if DYNAMIC_DATA.histogram_container is not None: histograms = DYNAMIC_DATA.histogram_container.get_histograms() bin_count = DYNAMIC_DATA.histogram_container.bin_count global_maximum = DYNAMIC_DATA.histogram_container.global_maximum if global_maximum > 0: if len(histograms) > 1: pens = self._color_pens self._painter.setCompositionMode(QPainter.CompositionMode_Plus) else: pens = [self._white_pen] histograms = [histograms[0]] self._painter.setCompositionMode(QPainter.CompositionMode_SourceOver) for pen, histogram in zip(pens, histograms): self._painter.save() self._painter.setPen(pen) for i, value in enumerate(histogram): x = round(i / bin_count * self.width()) bar_height = round(value / global_maximum * self.height()) self._painter.drawLine( x, self.height(), x, self.height() - (bar_height - HistogramView._TOP_MARGIN_IN_PX)) self._painter.restore() else: self._display_text("Invalid data") else: self._display_text("No data") self._painter.end()
@log def _display_text(self, text: str): font_inspector = self._painter.fontMetrics() text_height = font_inspector.height() text_width = font_inspector.width(text) self._painter.drawText( (self.width() - text_width) / 2, ((self.height() - text_height) / 2) + text_height, text)