Source code for QInstrument.instruments.Novanta.Opus.widget

from qtpy import QtCore
from QInstrument.lib.QInstrumentWidget import QInstrumentWidget
from QInstrument.instruments.Novanta.Opus.instrument import QOpus
from QInstrument.widgets.QLedWidget import QLedWidget
from QInstrument.widgets.QRotaryEncoderSpinBox import QRotaryEncoderSpinBox


[docs] class QOpusWidget(QInstrumentWidget): '''Control widget for a Laser Quantum Opus diode laser. Shows actual output power [W] and diode current [%] as read-only displays. The requested power setpoint is controlled with a rotary encoder spinbox (in Watts; converted to mW for the instrument). Laser emission is toggled with a push-button; a red LED alongside the button reflects the current emission state. The widget polls the instrument every :attr:`poll_interval` ms to refresh the read-only displays and the emission indicator. ''' UIFILE = 'OpusWidget.ui' poll_interval: int = 2000 # ms wsetter = QInstrumentWidget.wsetter | { 'QLedWidget': 'setValue', 'QRotaryEncoderSpinBox': 'setValue', } wgetter = QInstrumentWidget.wgetter | { 'QLedWidget': 'value', 'QRotaryEncoderSpinBox': 'value', } wsignal = QInstrumentWidget.wsignal | { 'QRotaryEncoderSpinBox': 'valueChanged', } def __init__(self, *args, device=None, **kwargs) -> None: device = device or QOpus().find() super().__init__(*args, device=device, **kwargs) self._timer = QtCore.QTimer(self) self._timer.setInterval(self.poll_interval) self._timer.timeout.connect(self._poll) if self.device is not None and self.device.isOpen(): self._setupControls() self._timer.start() def _setupControls(self) -> None: '''Configure the group box title, LED color, and power setpoint encoder. Called once after the device is confirmed open. Updates the group box title with the device wavelength if available, sets the emission LED to red, configures the ``power_setpoint`` rotary encoder appearance, and applies the current ``maximum_power`` as the encoder upper bound. ''' wavelength = getattr(type(self.device), 'WAVELENGTH', None) if wavelength is not None: self.groupBox.setTitle(f'Opus {int(wavelength)} nm DPSS Laser') self.emission.color = QLedWidget.RED self.power_setpoint.setTitle('Power [W]') self.power_setpoint.setSingleStep(0.01) self.power_setpoint.setDecimals(3) self.power_setpoint.setColors(('white', '#68ff00')) self._updatePowerRange() def _updatePowerRange(self) -> None: '''Apply ``maximum_power`` [mW] to the power setpoint encoder [W]. Called at setup and again after the first show event so that a ``maximum_power`` restored from the saved configuration is reflected in the encoder bounds. ''' max_p = float(self.device.get('maximum_power') or 1000.) self.power_setpoint.setMinimum(0.) self.power_setpoint.setMaximum(max_p / 1000.)
[docs] def showEvent(self, event) -> None: '''Re-apply power range after the first-show config restore.''' self._timer.stop() super().showEvent(event) if self.device is not None and self.device.isOpen(): self._updatePowerRange() self._timer.start()
def _connectSignals(self) -> None: '''Connect the emission toggle button and power setpoint encoder. Extends the base-class connection logic to manually wire the ``emission_button`` toggle and the ``power_setpoint`` encoder to their respective slots. ''' super()._connectSignals() self.emission_button.clicked.connect(self._toggleEmission) self.power_setpoint.valueChanged.connect(self._setPower) @QtCore.Slot(float) def _setPower(self, value: float) -> None: '''Transmit a new power setpoint to the device. Parameters ---------- value : float Requested power [W]; converted to mW before transmission. ''' self.device.set('power', value * 1000.) @QtCore.Slot() def _toggleEmission(self) -> None: '''Toggle laser emission on or off.''' self.device.set('emission', not bool(self.device.get('emission'))) @QtCore.Slot() def _poll(self) -> None: '''Read actual power, diode current, and emission state; update the UI. Converts the instrument power [mW] to Watts for the display. Only read-only status values are updated here; the power setpoint encoder is left untouched. ''' power = self.device.get('power') if power is not None: with QtCore.QSignalBlocker(self.power_display): self.power_display.setValue(float(power) / 1000.) current = self.device.get('current') if current is not None: with QtCore.QSignalBlocker(self.current_display): self.current_display.setValue(float(current)) emission = self.device.get('emission') if emission is not None: with QtCore.QSignalBlocker(self.emission): self.emission.setValue(bool(emission))
if __name__ == '__main__': QOpusWidget.example() __all__ = ['QOpusWidget']