# Module `redvox.api1000.gui.image_viewer`

Provides a basic image gallery for API M image sensors.

Expand source code

    """
    Provides a basic image gallery for API M image sensors.
    """

    try:
        import sys
        import datetime
        from typing import Optional, TYPE_CHECKING

        import numpy as np
        # pylint: disable=E0611
        from PySide6.QtCore import Qt, QByteArray
        # pylint: disable=E0611
        from PySide6.QtGui import QPixmap
        # pylint: disable=E0611
        from PySide6.QtWidgets import QApplication, QMainWindow, QWidget, QHBoxLayout, QLabel, QTableWidget, QTableWidgetItem, \
            QHeaderView, QSizePolicy, QAbstractItemView

        import redvox

        if TYPE_CHECKING:
            from redvox.api1000.wrapped_redvox_packet.sensors.image import Image

        class ImageSelectionWidget(QTableWidget):
            """
            This widget provides a table view of available images in the packet.
            """

            def __init__(self,
                         image_sensor: 'Image',
                         image_view_widget: 'ImageViewWidget',
                         parent: Optional[QWidget] = None) -> None:
                super().__init__(image_sensor.get_num_images(), 2, parent=parent)

                self.setSelectionBehavior(QAbstractItemView.SelectRows)
                self.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
                self.resizeColumnsToContents()

                extension: str = image_sensor.get_file_ext()
                timestamps: np.ndarray = image_sensor.get_timestamps().get_timestamps()

                self.setHorizontalHeaderLabels(["File Name", "Image Sampled At"])
                for (i, timestamp) in enumerate(timestamps):
                    name: str = f"{round(timestamp)}.{extension}"
                    date_time: datetime.datetime = datetime.datetime.utcfromtimestamp(timestamp / 1_000_000.0)
                    self.setItem(i, 0, QTableWidgetItem(name))
                    self.setItem(i, 1, QTableWidgetItem(str(date_time)))

                def __update_image_at_row(row: int) -> None:
                    buf: bytes = image_sensor.get_samples()[row]
                    image_view_widget.set_image(buf)

                self.currentCellChanged.connect(__update_image_at_row)

        class ImageViewWidget(QLabel):
            """
            This widget displays and scales the image
            """

            def __init__(self, _: Optional[QWidget] = None) -> None:
                super().__init__(parent=None)
                self.setAlignment(Qt.AlignCenter)

            def set_image(self, buf: bytes) -> None:
                """
                Sets the image.
                :param buf: Image bytes to set
                """
                pix: QPixmap = QPixmap()
                pix.loadFromData(QByteArray(buf))
                self.setPixmap(pix.scaled(self.width(),
                                          self.height(),
                                          Qt.AspectRatioMode.KeepAspectRatio,
                                          Qt.TransformationMode.SmoothTransformation))

        class ImageViewer(QWidget):
            """
            Widget that acts as the "main" widget into the application
            """

            def __init__(self, image_sensor: 'Image', parent: Optional[QWidget] = None) -> None:
                super().__init__(parent)
                self.setLayout(QHBoxLayout(self))

                image_view_widget: ImageViewWidget = ImageViewWidget()
                image_selection_widget: ImageSelectionWidget = ImageSelectionWidget(image_sensor, image_view_widget)
                size_policy: QSizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred)
                size_policy.setHorizontalStretch(1)
                image_selection_widget.setSizePolicy(size_policy)
                self.layout().addWidget(image_selection_widget)

                size_policy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
                size_policy.setHorizontalStretch(2)
                image_view_widget.setSizePolicy(size_policy)
                self.layout().addWidget(image_view_widget)

        class MainWindow(QMainWindow):
            """
            Main window of the application
            """

            def __init__(self, image_sensor: 'Image', parent: Optional[QWidget] = None) -> None:
                super().__init__(parent)
                self.setWindowTitle(f"RedVox Image Viewer v{redvox.VERSION}")
                self.setCentralWidget(ImageViewer(image_sensor, self))

        def start_gui(image_sensor: 'Image') -> None:
            """
            Starts the GUI from the provided image sensor.
            :param image_sensor: Image sensor
            """
            app: QApplication = QApplication(sys.argv)
            window: MainWindow = MainWindow(image_sensor)
            window.showMaximized()
            app.exec_()

    except ImportError:
        import warnings
        warnings.warn("GUI dependencies are not installed. Install the 'GUI' extra to enable this functionality.")

## Functions

`def start_gui(image_sensor: Image)`

  Starts the GUI from the provided image sensor. :param image_sensor: Image sensor

  Expand source code

      def start_gui(image_sensor: 'Image') -> None:
          """
          Starts the GUI from the provided image sensor.
          :param image_sensor: Image sensor
          """
          app: QApplication = QApplication(sys.argv)
          window: MainWindow = MainWindow(image_sensor)
          window.showMaximized()
          app.exec_()

## Classes

`class ImageSelectionWidget (image_sensor: Image, image_view_widget: ImageViewWidget, parent: Optional[PySide6.QtWidgets.QWidget] = None)`

  This widget provides a table view of available images in the packet.

  init(self, parent: Optional[PySide6.QtWidgets.QWidget] = None) -> None init(self, rows: int, columns: int, parent: Optional[PySide6.QtWidgets.QWidget] = None) -> None

  Initialize self. See help(type(self)) for accurate signature.

  Expand source code

      class ImageSelectionWidget(QTableWidget):
          """
          This widget provides a table view of available images in the packet.
          """

          def __init__(self,
                       image_sensor: 'Image',
                       image_view_widget: 'ImageViewWidget',
                       parent: Optional[QWidget] = None) -> None:
              super().__init__(image_sensor.get_num_images(), 2, parent=parent)

              self.setSelectionBehavior(QAbstractItemView.SelectRows)
              self.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
              self.resizeColumnsToContents()

              extension: str = image_sensor.get_file_ext()
              timestamps: np.ndarray = image_sensor.get_timestamps().get_timestamps()

              self.setHorizontalHeaderLabels(["File Name", "Image Sampled At"])
              for (i, timestamp) in enumerate(timestamps):
                  name: str = f"{round(timestamp)}.{extension}"
                  date_time: datetime.datetime = datetime.datetime.utcfromtimestamp(timestamp / 1_000_000.0)
                  self.setItem(i, 0, QTableWidgetItem(name))
                  self.setItem(i, 1, QTableWidgetItem(str(date_time)))

              def __update_image_at_row(row: int) -> None:
                  buf: bytes = image_sensor.get_samples()[row]
                  image_view_widget.set_image(buf)

              self.currentCellChanged.connect(__update_image_at_row)

  ### Ancestors

  - PySide6.QtWidgets.QTableWidget
  - PySide6.QtWidgets.QTableView
  - PySide6.QtWidgets.QAbstractItemView
  - PySide6.QtWidgets.QAbstractScrollArea
  - PySide6.QtWidgets.QFrame
  - PySide6.QtWidgets.QWidget
  - PySide6.QtCore.QObject
  - PySide6.QtGui.QPaintDevice
  - Shiboken.Object

  ### Class variables

  `var staticMetaObject`
`class ImageViewWidget`

  This widget displays and scales the image

  init(self, parent: Optional[PySide6.QtWidgets.QWidget] = None, f: PySide6.QtCore.Qt.WindowFlags = Default(Qt.WindowFlags)) -> None init(self, text: str, parent: Optional[PySide6.QtWidgets.QWidget] = None, f: PySide6.QtCore.Qt.WindowFlags = Default(Qt.WindowFlags)) -> None

  Initialize self. See help(type(self)) for accurate signature.

  Expand source code

      class ImageViewWidget(QLabel):
          """
          This widget displays and scales the image
          """

          def __init__(self, _: Optional[QWidget] = None) -> None:
              super().__init__(parent=None)
              self.setAlignment(Qt.AlignCenter)

          def set_image(self, buf: bytes) -> None:
              """
              Sets the image.
              :param buf: Image bytes to set
              """
              pix: QPixmap = QPixmap()
              pix.loadFromData(QByteArray(buf))
              self.setPixmap(pix.scaled(self.width(),
                                        self.height(),
                                        Qt.AspectRatioMode.KeepAspectRatio,
                                        Qt.TransformationMode.SmoothTransformation))

  ### Ancestors

  - PySide6.QtWidgets.QLabel
  - PySide6.QtWidgets.QFrame
  - PySide6.QtWidgets.QWidget
  - PySide6.QtCore.QObject
  - PySide6.QtGui.QPaintDevice
  - Shiboken.Object

  ### Class variables

  `var staticMetaObject`

  ### Methods

  `def set_image(self, buf: bytes) ‑> None`

    Sets the image. :param buf: Image bytes to set

    Expand source code

        def set_image(self, buf: bytes) -> None:
            """
            Sets the image.
            :param buf: Image bytes to set
            """
            pix: QPixmap = QPixmap()
            pix.loadFromData(QByteArray(buf))
            self.setPixmap(pix.scaled(self.width(),
                                      self.height(),
                                      Qt.AspectRatioMode.KeepAspectRatio,
                                      Qt.TransformationMode.SmoothTransformation))

`class ImageViewer (image_sensor: Image, parent: Optional[PySide6.QtWidgets.QWidget] = None)`

  Widget that acts as the "main" widget into the application

  init(self, parent: Optional[PySide6.QtWidgets.QWidget] = None, f: PySide6.QtCore.Qt.WindowFlags = Default(Qt.WindowFlags)) -> None

  Initialize self. See help(type(self)) for accurate signature.

  Expand source code

      class ImageViewer(QWidget):
          """
          Widget that acts as the "main" widget into the application
          """

          def __init__(self, image_sensor: 'Image', parent: Optional[QWidget] = None) -> None:
              super().__init__(parent)
              self.setLayout(QHBoxLayout(self))

              image_view_widget: ImageViewWidget = ImageViewWidget()
              image_selection_widget: ImageSelectionWidget = ImageSelectionWidget(image_sensor, image_view_widget)
              size_policy: QSizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred)
              size_policy.setHorizontalStretch(1)
              image_selection_widget.setSizePolicy(size_policy)
              self.layout().addWidget(image_selection_widget)

              size_policy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
              size_policy.setHorizontalStretch(2)
              image_view_widget.setSizePolicy(size_policy)
              self.layout().addWidget(image_view_widget)

  ### Ancestors

  - PySide6.QtWidgets.QWidget
  - PySide6.QtCore.QObject
  - PySide6.QtGui.QPaintDevice
  - Shiboken.Object

  ### Class variables

  `var staticMetaObject`
`class MainWindow (image_sensor: Image, parent: Optional[PySide6.QtWidgets.QWidget] = None)`

  Main window of the application

  init(self, parent: Optional[PySide6.QtWidgets.QWidget] = None, flags: PySide6.QtCore.Qt.WindowFlags = Default(Qt.WindowFlags)) -> None

  Initialize self. See help(type(self)) for accurate signature.

  Expand source code

      class MainWindow(QMainWindow):
          """
          Main window of the application
          """

          def __init__(self, image_sensor: 'Image', parent: Optional[QWidget] = None) -> None:
              super().__init__(parent)
              self.setWindowTitle(f"RedVox Image Viewer v{redvox.VERSION}")
              self.setCentralWidget(ImageViewer(image_sensor, self))

  ### Ancestors

  - PySide6.QtWidgets.QMainWindow
  - PySide6.QtWidgets.QWidget
  - PySide6.QtCore.QObject
  - PySide6.QtGui.QPaintDevice
  - Shiboken.Object

  ### Class variables

  `var staticMetaObject`