From ce9d62ca9c1d99ca021d7b6d181407cecb94d2ea Mon Sep 17 00:00:00 2001 From: fdrgsp Date: Tue, 19 Nov 2024 19:30:13 -0500 Subject: [PATCH] feat: enable/disable spinbox with right-click --- src/pymmcore_widgets/control/_stage_widget.py | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/pymmcore_widgets/control/_stage_widget.py b/src/pymmcore_widgets/control/_stage_widget.py index 66730852f..aa6bb913c 100644 --- a/src/pymmcore_widgets/control/_stage_widget.py +++ b/src/pymmcore_widgets/control/_stage_widget.py @@ -5,13 +5,14 @@ from fonticon_mdi6 import MDI6 from pymmcore_plus import CMMCorePlus, DeviceType, Keyword -from qtpy.QtCore import Qt, QTimerEvent, Signal +from qtpy.QtCore import QEvent, QObject, QPoint, Qt, QTimerEvent, Signal from qtpy.QtWidgets import ( QCheckBox, QDoubleSpinBox, QGridLayout, QHBoxLayout, QLabel, + QMenu, QPushButton, QRadioButton, QSpinBox, @@ -94,6 +95,28 @@ def __init__( self.setButtonSymbols(QSpinBox.ButtonSymbols.NoButtons) self.setAlignment(Qt.AlignmentFlag.AlignCenter) + # enable custom context menu handling for right-click events + self.setContextMenuPolicy(Qt.ContextMenuPolicy.NoContextMenu) + self.installEventFilter(self) + + def eventFilter(self, obj: QObject, event: QEvent) -> bool: + # listen to right-click events even when the spinbox is disabled + if obj is self and event.type() == QEvent.Type.ContextMenu: + self._on_context_menu(event.globalPos()) + return True + return super().eventFilter(obj, event) # type: ignore [no-any-return] + + def _on_context_menu(self, global_pos: QPoint) -> None: + menu = QMenu(self) + # update label based on the current state + label = "Disable Editing" if self.isEnabled() else "Enable Editing" + toggle_action = menu.addAction(label) + toggle_action.triggered.connect(self._toggle_enabled) + menu.exec(global_pos) + + def _toggle_enabled(self) -> None: + self.setEnabled(not self.isEnabled()) + class HaltButton(QPushButton): def __init__(self, device: str, core: CMMCorePlus, parent: QWidget | None = None):