Skip to content

Commit

Permalink
Merge pull request #4176 from EdgarGF93/play_slider
Browse files Browse the repository at this point in the history
HorizontalSliderWithBrowser: slider with play button
  • Loading branch information
t20100 authored Oct 7, 2024
2 parents 45bce37 + f1350ec commit 8d56b0f
Showing 1 changed file with 121 additions and 0 deletions.
121 changes: 121 additions & 0 deletions src/silx/gui/widgets/FrameBrowser.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
# THE SOFTWARE.
#
# ###########################################################################*/
from __future__ import annotations
"""This module defines two main classes:
- :class:`FrameBrowser`: a widget with 4 buttons (first, previous, next,
Expand Down Expand Up @@ -218,6 +219,70 @@ def setValue(self, value):
self._textChangedSlot()


class _SliderPlayWidgetAction(qt.QWidgetAction):

sigValueChanged = qt.Signal(int)

def __init__(
self,
parent: qt.QWidget | None = None,
label: str | None = None,
tooltip: str | None = None,
):
super().__init__(parent)
self._build(label=label, tooltip=tooltip)

def _build(self, label: str, tooltip: str):
widget = qt.QWidget()
layout = qt.QHBoxLayout()
widget.setLayout(layout)
self._spinbox = qt.QSpinBox()
self._spinbox.setToolTip(tooltip)
self._spinbox.setRange(1,1000000)
self._spinbox.valueChanged.connect(self.sigValueChanged)
label = qt.QLabel(label)
label.setToolTip(tooltip)
layout.addWidget(label)
layout.addWidget(self._spinbox)
self.setDefaultWidget(widget)

def value(self) -> int:
return self._spinbox.value()

def setValue(self, value: int):
self._spinbox.setValue(value)


class _PlayButtonContextMenu(qt.QMenu):

sigFrameRateChanged = qt.Signal(int)

def __init__(self, parent: qt.QWidget | None = None):
super().__init__(parent)
self._build()

def _build(self):
self._framerateAction = _SliderPlayWidgetAction(self, label="FPS:", tooltip="Display speed in frames per second")
self._framerateAction.sigValueChanged.connect(self.sigFrameRateChanged)
self._stepAction = _SliderPlayWidgetAction(self, label="Step:", tooltip="Step between displayed frames")
self.addAction(self._framerateAction)
self._framerateAction.setValue(10)
self.addAction(self._stepAction)
self._stepAction.setValue(1)

def getFrameRate(self) -> int:
return self._framerateAction.value()

def setFrameRate(self, rate: int):
self._framerateAction.setValue(rate)

def getStep(self) -> int:
return self._stepAction.value()

def setStep(self, interval: int):
self._stepAction.setValue(interval)


class HorizontalSliderWithBrowser(qt.QAbstractSlider):
"""
Slider widget combining a :class:`QSlider` and a :class:`FrameBrowser`.
Expand Down Expand Up @@ -254,6 +319,27 @@ def __init__(self, parent=None):
self._slider.valueChanged[int].connect(self._sliderSlot)
self._browser.sigIndexChanged.connect(self._browserSlot)

fontMetric = self.fontMetrics()
iconSize = qt.QSize(fontMetric.height(), fontMetric.height())

self.__timer = qt.QTimer(self)
self.__timer.timeout.connect(self._updateState)

self._playButton = qt.QToolButton(self)
self._playButton.setToolTip("Display dataset movie.")
self._playButton.setIcon(icons.getQIcon("camera"))
self._playButton.setIconSize(iconSize)
self._playButton.setCheckable(True)
self.mainLayout.addWidget(self._playButton)

self._playButton.toggled.connect(self._playButtonToggled)
self._menuPlaySlider = _PlayButtonContextMenu(self)
self._menuPlaySlider.sigFrameRateChanged.connect(self._frameRateChanged)
self._frameRateChanged(self.getFrameRate())
self._playButton.setMenu(self._menuPlaySlider)
self._playButton.setPopupMode(qt.QToolButton.MenuButtonPopup)


def lineEdit(self):
"""Returns the line edit provided by this widget.
Expand Down Expand Up @@ -312,3 +398,38 @@ def setValue(self, value):
def value(self):
"""Get selected value"""
return self._slider.value()

def setFrameRate(self, value: int):
"""Set the frame rate at which images are displayed"""
self._menuPlaySlider.setFrameRate(value)

def getFrameRate(self) -> int:
"""Get the frame rate at which images are displayed"""
return self._menuPlaySlider.getFrameRate()

def setPlayImageStep(self, value: int):
"""Set the step between displayed images when playing"""
self._menuPlaySlider.setStep(value)

def getPlayImageStep(self) -> int:
"""Returns the step between displayed images"""
return self._menuPlaySlider.getStep()

def _frameRateChanged(self, framerate: int):
"""Update the timer interval"""
self.__timer.setInterval(int(1 / framerate * 1e3))

def _playButtonToggled(self, checked: bool):
"""Start/Stop the slider sequence."""
if checked:
self.__timer.start()
return
self.__timer.stop()

def _updateState(self):
"""Advance an interval number of frames in the browser sequence."""
currentIndex = self._browser.getValue()
if currentIndex < self._browser.getRange()[-1]:
self.setValue(currentIndex + self.getPlayImageStep())
else:
self._playButton.setChecked(False)

0 comments on commit 8d56b0f

Please sign in to comment.