From 5a9fc470761c467f285064d83ebb8f93b168fcf4 Mon Sep 17 00:00:00 2001 From: Edgar Date: Sun, 29 Sep 2024 17:16:15 +0200 Subject: [PATCH 01/11] slider with play button --- src/silx/gui/data/NumpyAxesSelector.py | 4 +- src/silx/gui/widgets/FrameBrowser.py | 73 ++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 2 deletions(-) diff --git a/src/silx/gui/data/NumpyAxesSelector.py b/src/silx/gui/data/NumpyAxesSelector.py index d1e5412d5f..54bd11f1a0 100644 --- a/src/silx/gui/data/NumpyAxesSelector.py +++ b/src/silx/gui/data/NumpyAxesSelector.py @@ -32,7 +32,7 @@ import logging import numpy import functools -from silx.gui.widgets.FrameBrowser import HorizontalSliderWithBrowser +from silx.gui.widgets.FrameBrowser import HorizontalSliderWithBrowserPlay from silx.gui import qt from silx.gui.utils import blockSignals import silx.utils.weakref @@ -65,7 +65,7 @@ def __init__(self, parent=None): self.__label = qt.QLabel(self) self.__axes = qt.QComboBox(self) self.__axes.currentIndexChanged[int].connect(self.__axisMappingChanged) - self.__slider = HorizontalSliderWithBrowser(self) + self.__slider = HorizontalSliderWithBrowserPlay(self) self.__slider.valueChanged[int].connect(self.__sliderValueChanged) layout = qt.QHBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) diff --git a/src/silx/gui/widgets/FrameBrowser.py b/src/silx/gui/widgets/FrameBrowser.py index c03b2a8121..25f7ba2e19 100644 --- a/src/silx/gui/widgets/FrameBrowser.py +++ b/src/silx/gui/widgets/FrameBrowser.py @@ -312,3 +312,76 @@ def setValue(self, value): def value(self): """Get selected value""" return self._slider.value() + +class FrameRateWidgetAction(qt.QWidgetAction): + def __init__(self, parent): + super().__init__(parent) + self._build() + + def _build(self): + widget = qt.QWidget() + layout = qt.QHBoxLayout() + widget.setLayout(layout) + self.line_edit = qt.QLineEdit() + layout.addWidget(qt.QLabel("FPS:")) + layout.addWidget(self.line_edit) + self.setDefaultWidget(widget) + +class PlayButtonContextMenu(qt.QMenu): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self._build() + + def _build(self): + self.line_edit_action = FrameRateWidgetAction(self) + self.addAction(self.line_edit_action) + self.setFrameRate("10") + + def setFrameRate(self, value:str): + self.line_edit_action.line_edit.setText(value) + + def getFrameRate(self): + return int(self.line_edit_action.line_edit.text()) + +class HorizontalSliderWithBrowserPlay(HorizontalSliderWithBrowser): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + self.__timer = qt.QTimer(self) + self.__timer.timeout.connect(self._updateState) + + fontMetric = self.fontMetrics() + iconSize = qt.QSize(fontMetric.height(), fontMetric.height()) + + self.playButton = qt.QPushButton(self) + self.playButton.setIcon(icons.getQIcon("camera")) + self.playButton.setIconSize(iconSize) + self.mainLayout.addWidget(self.playButton) + + self.playButton.clicked.connect(self._playStopSequence) + self.menu = PlayButtonContextMenu(self) + + def contextMenuEvent(self, event): + self.menu.exec_(self.mapToGlobal(event.pos())) + + def _playStopSequence(self): + if self.__timer.isActive(): + self._stopTimer() + else: + self._startTimer() + + def _updateState(self): + if self._browser.getValue() < self._browser.getRange()[-1]: + self._browser._nextClicked() + else: + self._stopTimer() + + def _startTimer(self): + framerate = self.menu.getFrameRate() + waiting_time_ms = int(1 / framerate * 1e3) + self.__timer.start(waiting_time_ms) + self.playButton.setIcon(icons.getQIcon("close")) + + def _stopTimer(self): + self.__timer.stop() + self.playButton.setIcon(icons.getQIcon("camera")) \ No newline at end of file From 3d3aab7fd32a283d94b751b48d54e10181d5cddf Mon Sep 17 00:00:00 2001 From: Edgar Gutierrez Fernandez Date: Tue, 1 Oct 2024 09:14:15 +0200 Subject: [PATCH 02/11] spinbox interval --- src/silx/gui/widgets/FrameBrowser.py | 30 +++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/src/silx/gui/widgets/FrameBrowser.py b/src/silx/gui/widgets/FrameBrowser.py index 25f7ba2e19..1c35d1d45d 100644 --- a/src/silx/gui/widgets/FrameBrowser.py +++ b/src/silx/gui/widgets/FrameBrowser.py @@ -325,7 +325,21 @@ def _build(self): self.line_edit = qt.QLineEdit() layout.addWidget(qt.QLabel("FPS:")) layout.addWidget(self.line_edit) - self.setDefaultWidget(widget) + self.setDefaultWidget(widget) + +class IntervalsWidgetAction(qt.QWidgetAction): + def __init__(self, parent): + super().__init__(parent) + self._build() + + def _build(self): + widget = qt.QWidget() + layout = qt.QHBoxLayout() + widget.setLayout(layout) + self.spinbox = qt.QSpinBox() + layout.addWidget(qt.QLabel("Interval:")) + layout.addWidget(self.spinbox) + self.setDefaultWidget(widget) class PlayButtonContextMenu(qt.QMenu): def __init__(self, *args, **kwargs): @@ -334,14 +348,23 @@ def __init__(self, *args, **kwargs): def _build(self): self.line_edit_action = FrameRateWidgetAction(self) + self.interval_action = IntervalsWidgetAction(self) self.addAction(self.line_edit_action) - self.setFrameRate("10") + self.setFrameRate(value="10") + self.addAction(self.interval_action) + self.setInterval(value=1) def setFrameRate(self, value:str): self.line_edit_action.line_edit.setText(value) def getFrameRate(self): return int(self.line_edit_action.line_edit.text()) + + def setInterval(self, value:int): + self.interval_action.spinbox.setValue(value) + + def getInterval(self): + return int(self.interval_action.spinbox.value()) class HorizontalSliderWithBrowserPlay(HorizontalSliderWithBrowser): def __init__(self, *args, **kwargs): @@ -371,8 +394,9 @@ def _playStopSequence(self): self._startTimer() def _updateState(self): + interval = self.menu.getInterval() if self._browser.getValue() < self._browser.getRange()[-1]: - self._browser._nextClicked() + self.setValue(self._browser.getValue() + interval) else: self._stopTimer() From bd34c188d2e497941b58697bd39cb148981dae61 Mon Sep 17 00:00:00 2001 From: Edgar Gutierrez Fernandez Date: Sat, 5 Oct 2024 11:25:33 +0200 Subject: [PATCH 03/11] add to horizontalslider --- src/silx/gui/data/NumpyAxesSelector.py | 4 +- src/silx/gui/widgets/FrameBrowser.py | 127 +++++++++++-------------- 2 files changed, 58 insertions(+), 73 deletions(-) diff --git a/src/silx/gui/data/NumpyAxesSelector.py b/src/silx/gui/data/NumpyAxesSelector.py index 54bd11f1a0..d1e5412d5f 100644 --- a/src/silx/gui/data/NumpyAxesSelector.py +++ b/src/silx/gui/data/NumpyAxesSelector.py @@ -32,7 +32,7 @@ import logging import numpy import functools -from silx.gui.widgets.FrameBrowser import HorizontalSliderWithBrowserPlay +from silx.gui.widgets.FrameBrowser import HorizontalSliderWithBrowser from silx.gui import qt from silx.gui.utils import blockSignals import silx.utils.weakref @@ -65,7 +65,7 @@ def __init__(self, parent=None): self.__label = qt.QLabel(self) self.__axes = qt.QComboBox(self) self.__axes.currentIndexChanged[int].connect(self.__axisMappingChanged) - self.__slider = HorizontalSliderWithBrowserPlay(self) + self.__slider = HorizontalSliderWithBrowser(self) self.__slider.valueChanged[int].connect(self.__sliderValueChanged) layout = qt.QHBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) diff --git a/src/silx/gui/widgets/FrameBrowser.py b/src/silx/gui/widgets/FrameBrowser.py index 1c35d1d45d..297815bfe8 100644 --- a/src/silx/gui/widgets/FrameBrowser.py +++ b/src/silx/gui/widgets/FrameBrowser.py @@ -217,6 +217,36 @@ def setValue(self, value): self._lineEdit.setText("%d" % value) self._textChangedSlot() +class SliderPlayWidgetAction(qt.QWidgetAction): + def __init__(self, parent, label=None, tooltip=None): + super().__init__(parent) + self._build(label=label, tooltip=tooltip) + + def _build(self, label=None, tooltip=None): + widget = qt.QWidget() + layout = qt.QHBoxLayout() + widget.setLayout(layout) + self._spinbox = qt.QSpinBox() + self._spinbox.setToolTip(tooltip) + self._spinbox.setRange(1,1000000) + label = qt.QLabel(label) + label.setToolTip(tooltip) + layout.addWidget(label) + layout.addWidget(self._spinbox) + self.setDefaultWidget(widget) + +class _PlayButtonContextMenu(qt.QMenu): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self._build() + + def _build(self): + self._framerate_action = SliderPlayWidgetAction(self, label="FPS:", tooltip="Display speed in frames per second") + self._interval_action = SliderPlayWidgetAction(self, label="Interval:", tooltip="Jump between frames") + self.addAction(self._framerate_action) + self._framerate_action._spinbox.setValue(10) + self.addAction(self._interval_action) + self._interval_action._spinbox.setValue(1) class HorizontalSliderWithBrowser(qt.QAbstractSlider): """ @@ -254,6 +284,23 @@ 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 movie with frames") + self._playButton.setIcon(icons.getQIcon("camera")) + self._playButton.setIconSize(iconSize) + self.mainLayout.addWidget(self._playButton) + + self._playButton.clicked.connect(self._playStopSequence) + self._menuPlaySlider = _PlayButtonContextMenu(self) + self._playButton.setMenu(self._menuPlaySlider) + self._playButton.setPopupMode(1) + def lineEdit(self): """Returns the line edit provided by this widget. @@ -313,79 +360,17 @@ def value(self): """Get selected value""" return self._slider.value() -class FrameRateWidgetAction(qt.QWidgetAction): - def __init__(self, parent): - super().__init__(parent) - self._build() - - def _build(self): - widget = qt.QWidget() - layout = qt.QHBoxLayout() - widget.setLayout(layout) - self.line_edit = qt.QLineEdit() - layout.addWidget(qt.QLabel("FPS:")) - layout.addWidget(self.line_edit) - self.setDefaultWidget(widget) - -class IntervalsWidgetAction(qt.QWidgetAction): - def __init__(self, parent): - super().__init__(parent) - self._build() - - def _build(self): - widget = qt.QWidget() - layout = qt.QHBoxLayout() - widget.setLayout(layout) - self.spinbox = qt.QSpinBox() - layout.addWidget(qt.QLabel("Interval:")) - layout.addWidget(self.spinbox) - self.setDefaultWidget(widget) - -class PlayButtonContextMenu(qt.QMenu): - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self._build() - - def _build(self): - self.line_edit_action = FrameRateWidgetAction(self) - self.interval_action = IntervalsWidgetAction(self) - self.addAction(self.line_edit_action) - self.setFrameRate(value="10") - self.addAction(self.interval_action) - self.setInterval(value=1) - - def setFrameRate(self, value:str): - self.line_edit_action.line_edit.setText(value) + def setFrameRate(self, value:int): + self._menuPlaySlider._framerate_action._spinbox.setValue(value) def getFrameRate(self): - return int(self.line_edit_action.line_edit.text()) + return int(self._menuPlaySlider._framerate_action._spinbox.value()) def setInterval(self, value:int): - self.interval_action.spinbox.setValue(value) + self._menuPlaySlider._interval_action._spinbox.setValue(value) def getInterval(self): - return int(self.interval_action.spinbox.value()) - -class HorizontalSliderWithBrowserPlay(HorizontalSliderWithBrowser): - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - - self.__timer = qt.QTimer(self) - self.__timer.timeout.connect(self._updateState) - - fontMetric = self.fontMetrics() - iconSize = qt.QSize(fontMetric.height(), fontMetric.height()) - - self.playButton = qt.QPushButton(self) - self.playButton.setIcon(icons.getQIcon("camera")) - self.playButton.setIconSize(iconSize) - self.mainLayout.addWidget(self.playButton) - - self.playButton.clicked.connect(self._playStopSequence) - self.menu = PlayButtonContextMenu(self) - - def contextMenuEvent(self, event): - self.menu.exec_(self.mapToGlobal(event.pos())) + return int(self._menuPlaySlider._interval_action._spinbox.value()) def _playStopSequence(self): if self.__timer.isActive(): @@ -394,18 +379,18 @@ def _playStopSequence(self): self._startTimer() def _updateState(self): - interval = self.menu.getInterval() + interval = self.getInterval() if self._browser.getValue() < self._browser.getRange()[-1]: self.setValue(self._browser.getValue() + interval) else: self._stopTimer() def _startTimer(self): - framerate = self.menu.getFrameRate() + framerate = self.getFrameRate() waiting_time_ms = int(1 / framerate * 1e3) self.__timer.start(waiting_time_ms) - self.playButton.setIcon(icons.getQIcon("close")) + self._playButton.setIcon(icons.getQIcon("close")) def _stopTimer(self): self.__timer.stop() - self.playButton.setIcon(icons.getQIcon("camera")) \ No newline at end of file + self._playButton.setIcon(icons.getQIcon("camera")) From 82c6e4cd7d9903422a626d55ce1c38401a5ce3f3 Mon Sep 17 00:00:00 2001 From: Edgar Date: Sun, 6 Oct 2024 11:22:44 +0200 Subject: [PATCH 04/11] qt.QToolButton.MenuButtonPopup --- src/silx/gui/widgets/FrameBrowser.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/silx/gui/widgets/FrameBrowser.py b/src/silx/gui/widgets/FrameBrowser.py index 297815bfe8..a36b99b6bb 100644 --- a/src/silx/gui/widgets/FrameBrowser.py +++ b/src/silx/gui/widgets/FrameBrowser.py @@ -299,7 +299,7 @@ def __init__(self, parent=None): self._playButton.clicked.connect(self._playStopSequence) self._menuPlaySlider = _PlayButtonContextMenu(self) self._playButton.setMenu(self._menuPlaySlider) - self._playButton.setPopupMode(1) + self._playButton.setPopupMode(qt.QToolButton.MenuButtonPopup) def lineEdit(self): """Returns the line edit provided by this widget. From 5a2468345a0f1232d96730c1f75e69f4eee35a55 Mon Sep 17 00:00:00 2001 From: Edgar Date: Sun, 6 Oct 2024 11:35:23 +0200 Subject: [PATCH 05/11] methods, doc, typing --- src/silx/gui/widgets/FrameBrowser.py | 32 +++++++++++++++++++++------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/src/silx/gui/widgets/FrameBrowser.py b/src/silx/gui/widgets/FrameBrowser.py index a36b99b6bb..650d799420 100644 --- a/src/silx/gui/widgets/FrameBrowser.py +++ b/src/silx/gui/widgets/FrameBrowser.py @@ -359,26 +359,40 @@ def setValue(self, value): def value(self): """Get selected value""" return self._slider.value() + + def spinBoxFrameRate(self) -> qt.QSpinBox: + """Returns the SpinBox widget for FrameRate display.""" + return self._menuPlaySlider._framerate_action._spinbox + + def spinBoxInterval(self) -> qt.QSpinBox: + """Returns the SpinBox widget for interval display.""" + return self._menuPlaySlider._interval_action._spinbox - def setFrameRate(self, value:int): - self._menuPlaySlider._framerate_action._spinbox.setValue(value) + def setFrameRate(self, value: int): + """Set the FrameRate value for the PlaySlider""" + self.spinBoxFrameRate().setValue(value) - def getFrameRate(self): - return int(self._menuPlaySlider._framerate_action._spinbox.value()) + def getFrameRate(self) -> int: + """Returns the value from the FrameRate SpinBox.""" + return int(self.spinBoxFrameRate().value()) - def setInterval(self, value:int): - self._menuPlaySlider._interval_action._spinbox.setValue(value) + def setInterval(self, value: int): + """Set the Interval value for the PlaySlider""" + self.spinBoxInterval().setValue(value) - def getInterval(self): - return int(self._menuPlaySlider._interval_action._spinbox.value()) + def getInterval(self) -> int: + """Returns the value from the Interval SpinBox.""" + return int(self.spinBoxInterval().value()) def _playStopSequence(self): + """Start/Stop the slider sequence.""" if self.__timer.isActive(): self._stopTimer() else: self._startTimer() def _updateState(self): + """Advance an interval number of frames in the browser sequence.""" interval = self.getInterval() if self._browser.getValue() < self._browser.getRange()[-1]: self.setValue(self._browser.getValue() + interval) @@ -386,11 +400,13 @@ def _updateState(self): self._stopTimer() def _startTimer(self): + """Start the slider sequence.""" framerate = self.getFrameRate() waiting_time_ms = int(1 / framerate * 1e3) self.__timer.start(waiting_time_ms) self._playButton.setIcon(icons.getQIcon("close")) def _stopTimer(self): + """Stop the slider sequence.""" self.__timer.stop() self._playButton.setIcon(icons.getQIcon("camera")) From 1157d90126a83cb15f236ff0daefc3194290020b Mon Sep 17 00:00:00 2001 From: Edgar Date: Sun, 6 Oct 2024 11:38:28 +0200 Subject: [PATCH 06/11] simplify --- src/silx/gui/widgets/FrameBrowser.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/silx/gui/widgets/FrameBrowser.py b/src/silx/gui/widgets/FrameBrowser.py index 650d799420..d51cda10b7 100644 --- a/src/silx/gui/widgets/FrameBrowser.py +++ b/src/silx/gui/widgets/FrameBrowser.py @@ -393,9 +393,8 @@ def _playStopSequence(self): def _updateState(self): """Advance an interval number of frames in the browser sequence.""" - interval = self.getInterval() if self._browser.getValue() < self._browser.getRange()[-1]: - self.setValue(self._browser.getValue() + interval) + self.setValue(self._browser.getValue() + self.getInterval()) else: self._stopTimer() From f1fb7f41c3f890204b3e2baf1546e90b1ee89ea8 Mon Sep 17 00:00:00 2001 From: Edgar Date: Sun, 6 Oct 2024 11:41:00 +0200 Subject: [PATCH 07/11] current_index --- src/silx/gui/widgets/FrameBrowser.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/silx/gui/widgets/FrameBrowser.py b/src/silx/gui/widgets/FrameBrowser.py index d51cda10b7..0f8275d458 100644 --- a/src/silx/gui/widgets/FrameBrowser.py +++ b/src/silx/gui/widgets/FrameBrowser.py @@ -393,8 +393,9 @@ def _playStopSequence(self): def _updateState(self): """Advance an interval number of frames in the browser sequence.""" - if self._browser.getValue() < self._browser.getRange()[-1]: - self.setValue(self._browser.getValue() + self.getInterval()) + current_index = self._browser.getValue() + if current_index < self._browser.getRange()[-1]: + self.setValue(current_index + self.getInterval()) else: self._stopTimer() From af0efa5bc8f3799c3ac1eaf1a2d9edb5b6e43911 Mon Sep 17 00:00:00 2001 From: Thomas VINCENT Date: Mon, 7 Oct 2024 12:14:51 +0200 Subject: [PATCH 08/11] Use CamelCase, do not use private attributes add typing --- src/silx/gui/widgets/FrameBrowser.py | 75 +++++++++++++++++----------- 1 file changed, 47 insertions(+), 28 deletions(-) diff --git a/src/silx/gui/widgets/FrameBrowser.py b/src/silx/gui/widgets/FrameBrowser.py index 0f8275d458..4244aebeff 100644 --- a/src/silx/gui/widgets/FrameBrowser.py +++ b/src/silx/gui/widgets/FrameBrowser.py @@ -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, @@ -217,12 +218,18 @@ def setValue(self, value): self._lineEdit.setText("%d" % value) self._textChangedSlot() -class SliderPlayWidgetAction(qt.QWidgetAction): - def __init__(self, parent, label=None, tooltip=None): + +class _SliderPlayWidgetAction(qt.QWidgetAction): + 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=None, tooltip=None): + def _build(self, label: str, tooltip: str): widget = qt.QWidget() layout = qt.QHBoxLayout() widget.setLayout(layout) @@ -235,18 +242,38 @@ def _build(self, label=None, tooltip=None): 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): - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) + def __init__(self, parent: qt.QWidget | None = None): + super().__init__(parent) self._build() def _build(self): - self._framerate_action = SliderPlayWidgetAction(self, label="FPS:", tooltip="Display speed in frames per second") - self._interval_action = SliderPlayWidgetAction(self, label="Interval:", tooltip="Jump between frames") - self.addAction(self._framerate_action) - self._framerate_action._spinbox.setValue(10) - self.addAction(self._interval_action) - self._interval_action._spinbox.setValue(1) + self._framerateAction = _SliderPlayWidgetAction(self, label="FPS:", tooltip="Display speed in frames per second") + self._intervalAction = _SliderPlayWidgetAction(self, label="Interval:", tooltip="Jump between frames") + self.addAction(self._framerateAction) + self._framerateAction.setValue(10) + self.addAction(self._intervalAction) + self._intervalAction.setValue(1) + + def getFrameRate(self) -> int: + return self._framerateAction.value() + + def setFrameRate(self, rate: int): + self._framerateAction.setValue(rate) + + def getInterval(self) -> int: + return self._intervalAction.value() + + def setInterval(self, interval: int): + self._intervalAction.setValue(interval) + class HorizontalSliderWithBrowser(qt.QAbstractSlider): """ @@ -360,29 +387,21 @@ def value(self): """Get selected value""" return self._slider.value() - def spinBoxFrameRate(self) -> qt.QSpinBox: - """Returns the SpinBox widget for FrameRate display.""" - return self._menuPlaySlider._framerate_action._spinbox - - def spinBoxInterval(self) -> qt.QSpinBox: - """Returns the SpinBox widget for interval display.""" - return self._menuPlaySlider._interval_action._spinbox - def setFrameRate(self, value: int): """Set the FrameRate value for the PlaySlider""" - self.spinBoxFrameRate().setValue(value) + self._menuPlaySlider.setFrameRate(value) def getFrameRate(self) -> int: """Returns the value from the FrameRate SpinBox.""" - return int(self.spinBoxFrameRate().value()) + return self._menuPlaySlider.getFrameRate() def setInterval(self, value: int): """Set the Interval value for the PlaySlider""" - self.spinBoxInterval().setValue(value) + self._menuPlaySlider.setInterval(value) def getInterval(self) -> int: """Returns the value from the Interval SpinBox.""" - return int(self.spinBoxInterval().value()) + return self._menuPlaySlider.getInterval() def _playStopSequence(self): """Start/Stop the slider sequence.""" @@ -393,17 +412,17 @@ def _playStopSequence(self): def _updateState(self): """Advance an interval number of frames in the browser sequence.""" - current_index = self._browser.getValue() - if current_index < self._browser.getRange()[-1]: - self.setValue(current_index + self.getInterval()) + currentIndex = self._browser.getValue() + if currentIndex < self._browser.getRange()[-1]: + self.setValue(currentIndex + self.getInterval()) else: self._stopTimer() def _startTimer(self): """Start the slider sequence.""" framerate = self.getFrameRate() - waiting_time_ms = int(1 / framerate * 1e3) - self.__timer.start(waiting_time_ms) + waitingTimeMS = int(1 / framerate * 1e3) + self.__timer.start(waitingTimeMS) self._playButton.setIcon(icons.getQIcon("close")) def _stopTimer(self): From d749c065a91ddea7a0d8586cb53d2b98c1f27aad Mon Sep 17 00:00:00 2001 From: Thomas VINCENT Date: Mon, 7 Oct 2024 13:05:48 +0200 Subject: [PATCH 09/11] rework the control of the QTimer --- src/silx/gui/widgets/FrameBrowser.py | 44 +++++++++++++++------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/src/silx/gui/widgets/FrameBrowser.py b/src/silx/gui/widgets/FrameBrowser.py index 4244aebeff..93b5646039 100644 --- a/src/silx/gui/widgets/FrameBrowser.py +++ b/src/silx/gui/widgets/FrameBrowser.py @@ -220,6 +220,9 @@ def setValue(self, value): class _SliderPlayWidgetAction(qt.QWidgetAction): + + sigValueChanged = qt.Signal(int) + def __init__( self, parent: qt.QWidget | None = None, @@ -236,6 +239,7 @@ def _build(self, label: str, tooltip: str): 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) @@ -250,12 +254,16 @@ def setValue(self, value: int): 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._intervalAction = _SliderPlayWidgetAction(self, label="Interval:", tooltip="Jump between frames") self.addAction(self._framerateAction) self._framerateAction.setValue(10) @@ -321,13 +329,17 @@ def __init__(self, parent=None): self._playButton.setToolTip("Display movie with frames") self._playButton.setIcon(icons.getQIcon("camera")) self._playButton.setIconSize(iconSize) + self._playButton.setCheckable(True) self.mainLayout.addWidget(self._playButton) - self._playButton.clicked.connect(self._playStopSequence) + self._playButton.toggled.connect(self._playButtonToggled) self._menuPlaySlider = _PlayButtonContextMenu(self) + self._menuPlaySlider.sigFrameRateChanged.connect(self._frameRateChanged) + self._frameRateChanged(self._menuPlaySlider.getInterval()) self._playButton.setMenu(self._menuPlaySlider) self._playButton.setPopupMode(qt.QToolButton.MenuButtonPopup) + def lineEdit(self): """Returns the line edit provided by this widget. @@ -402,30 +414,22 @@ def setInterval(self, value: int): def getInterval(self) -> int: """Returns the value from the Interval SpinBox.""" return self._menuPlaySlider.getInterval() + + def _frameRateChanged(self, framerate: int): + """Update the timer interval""" + self.__timer.setInterval(int(1 / framerate * 1e3)) - def _playStopSequence(self): + def _playButtonToggled(self, checked: bool): """Start/Stop the slider sequence.""" - if self.__timer.isActive(): - self._stopTimer() - else: - self._startTimer() - + 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.getInterval()) else: - self._stopTimer() - - def _startTimer(self): - """Start the slider sequence.""" - framerate = self.getFrameRate() - waitingTimeMS = int(1 / framerate * 1e3) - self.__timer.start(waitingTimeMS) - self._playButton.setIcon(icons.getQIcon("close")) - - def _stopTimer(self): - """Stop the slider sequence.""" - self.__timer.stop() - self._playButton.setIcon(icons.getQIcon("camera")) + self._playButton.setChecked(False) From 96d35a29a21038e3bf818af9cbd74e5b586dcfb0 Mon Sep 17 00:00:00 2001 From: Thomas VINCENT Date: Mon, 7 Oct 2024 13:14:02 +0200 Subject: [PATCH 10/11] rename interval by play image step --- src/silx/gui/widgets/FrameBrowser.py | 34 ++++++++++++++-------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/silx/gui/widgets/FrameBrowser.py b/src/silx/gui/widgets/FrameBrowser.py index 93b5646039..16e744bffc 100644 --- a/src/silx/gui/widgets/FrameBrowser.py +++ b/src/silx/gui/widgets/FrameBrowser.py @@ -264,11 +264,11 @@ def __init__(self, parent: qt.QWidget | None = None): def _build(self): self._framerateAction = _SliderPlayWidgetAction(self, label="FPS:", tooltip="Display speed in frames per second") self._framerateAction.sigValueChanged.connect(self.sigFrameRateChanged) - self._intervalAction = _SliderPlayWidgetAction(self, label="Interval:", tooltip="Jump between frames") + self._stepAction = _SliderPlayWidgetAction(self, label="Step:", tooltip="Step between displayed frames") self.addAction(self._framerateAction) self._framerateAction.setValue(10) - self.addAction(self._intervalAction) - self._intervalAction.setValue(1) + self.addAction(self._stepAction) + self._stepAction.setValue(1) def getFrameRate(self) -> int: return self._framerateAction.value() @@ -276,11 +276,11 @@ def getFrameRate(self) -> int: def setFrameRate(self, rate: int): self._framerateAction.setValue(rate) - def getInterval(self) -> int: - return self._intervalAction.value() + def getStep(self) -> int: + return self._stepAction.value() - def setInterval(self, interval: int): - self._intervalAction.setValue(interval) + def setStep(self, interval: int): + self._stepAction.setValue(interval) class HorizontalSliderWithBrowser(qt.QAbstractSlider): @@ -335,7 +335,7 @@ def __init__(self, parent=None): self._playButton.toggled.connect(self._playButtonToggled) self._menuPlaySlider = _PlayButtonContextMenu(self) self._menuPlaySlider.sigFrameRateChanged.connect(self._frameRateChanged) - self._frameRateChanged(self._menuPlaySlider.getInterval()) + self._frameRateChanged(self.getFrameRate()) self._playButton.setMenu(self._menuPlaySlider) self._playButton.setPopupMode(qt.QToolButton.MenuButtonPopup) @@ -400,20 +400,20 @@ def value(self): return self._slider.value() def setFrameRate(self, value: int): - """Set the FrameRate value for the PlaySlider""" + """Set the frame rate at which images are displayed""" self._menuPlaySlider.setFrameRate(value) def getFrameRate(self) -> int: - """Returns the value from the FrameRate SpinBox.""" + """Get the frame rate at which images are displayed""" return self._menuPlaySlider.getFrameRate() - def setInterval(self, value: int): - """Set the Interval value for the PlaySlider""" - self._menuPlaySlider.setInterval(value) + def setPlayImageStep(self, value: int): + """Set the step between displayed images when playing""" + self._menuPlaySlider.setStep(value) - def getInterval(self) -> int: - """Returns the value from the Interval SpinBox.""" - return self._menuPlaySlider.getInterval() + def getPlayImageStep(self) -> int: + """Returns the step between displayed images""" + return self._menuPlaySlider.getStep() def _frameRateChanged(self, framerate: int): """Update the timer interval""" @@ -430,6 +430,6 @@ 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.getInterval()) + self.setValue(currentIndex + self.getPlayImageStep()) else: self._playButton.setChecked(False) From f1350ec0d17d75ccb7787954fe85006a355a2ec2 Mon Sep 17 00:00:00 2001 From: Edgar Gutierrez Fernandez Date: Mon, 7 Oct 2024 15:12:41 +0200 Subject: [PATCH 11/11] tooltip --- src/silx/gui/widgets/FrameBrowser.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/silx/gui/widgets/FrameBrowser.py b/src/silx/gui/widgets/FrameBrowser.py index 16e744bffc..8275a3657c 100644 --- a/src/silx/gui/widgets/FrameBrowser.py +++ b/src/silx/gui/widgets/FrameBrowser.py @@ -326,7 +326,7 @@ def __init__(self, parent=None): self.__timer.timeout.connect(self._updateState) self._playButton = qt.QToolButton(self) - self._playButton.setToolTip("Display movie with frames") + self._playButton.setToolTip("Display dataset movie.") self._playButton.setIcon(icons.getQIcon("camera")) self._playButton.setIconSize(iconSize) self._playButton.setCheckable(True)