qt_device_adapter#

Qt adapter that bridges pure-Python device signals into ``pyqtSignal``s.

GUI code (e.g. live plotting, image previews) needs Qt signals so that emissions are delivered on the main thread with QueuedConnection semantics. Devices built on mesofield.devices.base.BaseDataProducer use psygnal and remain Qt-free. This module is the seam: attach an adapter to a device, expose the adapter’s pyqtSignal as an attribute on the device, and the GUI reads that attribute.

Two adapters live here:

  • QtDeviceAdapter — for serial-style devices. Bridges signals.data into serialDataReceived / serialSpeedUpdated.

  • QtImageAdapter — for camera-shaped devices. Provides an image_ready(np.ndarray) pyqtSignal that the MDA viewer subscribes to. The device pushes frames into the adapter via adapter.emit_frame(frame).

class mesofield.gui.qt_device_adapter.QtDeviceAdapter[source]#

Bases: QObject

Bridges device.signals.data into Qt-friendly emissions.

Subscribes to the device’s signals.data and re-emits:

  • serialDataReceived(object) — the raw payload.

  • serialSpeedUpdated(float, float)(time_s, speed) whenever the payload is a dict carrying a "speed" key. time_s defaults to the device timestamp; if absent, the queue timestamp.

__init__(device)[source]#
Parameters:

device (Any)

Return type:

None

class mesofield.gui.qt_device_adapter.QtImageAdapter[source]#

Bases: QObject

Bridges per-frame ndarray emissions into a Qt image_ready signal.

The MDA gui’s static-viewer branch subscribes via preview = ImagePreview(image_payload=cam.image_ready, ...), which calls image_payload.connect(cb, type=QueuedConnection) – so image_ready MUST be a real pyqtSignal. Devices built on BaseDataProducer are non-Qt; they hold an instance of this adapter and expose its image_ready attribute as their own.

Usage:

class MyCam(BaseDataProducer):
    def __init__(self, cfg=None, **kwargs):
        super().__init__(cfg, **kwargs)
        self._qt_image_adapter = QtImageAdapter()
        self.image_ready = self._qt_image_adapter.image_ready

    def _run_loop(self):
        ...
        self._qt_image_adapter.emit_frame(frame)