Skip to main content

ezmsg-qt

Qt-native pub/sub runtime for connecting GUIs to ezmsg graphs.

Overview

ezmsg-qt lets Qt widgets publish to and subscribe from ezmsg topics using a familiar signal/slot style while keeping ezmsg runtime ownership explicit.

  • EzSession owns the ezmsg runtime thread, GraphContext, and sidecar pipelines
  • EzSubscriber and EzPublisher attach to a session
  • ProcessorChain compiles processing stages into a sidecar runtime owned by the session

Quick Start

from enum import Enum, auto
from qtpy import QtWidgets

from ezmsg.qt import EzPublisher, EzSession, EzSubscriber


class VelocityTopic(Enum):
    INPUT_SETTINGS = auto()
    OUTPUT_DATA = auto()


class VelocityWidget(QtWidgets.QWidget):
    def __init__(self, session: EzSession):
        super().__init__()

        self.slider = QtWidgets.QSlider()
        self.label = QtWidgets.QLabel("Waiting for data...")

        self.data_sub = EzSubscriber(
            VelocityTopic.OUTPUT_DATA,
            parent=self,
            session=session,
        )
        self.settings_pub = EzPublisher(
            VelocityTopic.INPUT_SETTINGS,
            parent=self,
            session=session,
        )

        self.data_sub.connect(self.on_data)
        self.slider.valueChanged.connect(self.on_slider)

    def on_data(self, msg):
        self.label.setText(f"Received: {msg}")

    def on_slider(self, value):
        self.settings_pub.emit({"gain": value})


def main() -> None:
    app = QtWidgets.QApplication([])
    session = EzSession()
    window = VelocityWidget(session)
    window.show()

    with session:
        app.exec()

Runtime Topic Switching

EzSubscriber can retarget to a new topic at runtime without reconnecting Qt slots.

class TopicSwitcher(QtWidgets.QWidget):
    def __init__(self, session: EzSession):
        super().__init__()
        self.sub = EzSubscriber(MyTopic.A, parent=self, session=session)
        self.sub.connect(self.on_data)

    def switch_to_b(self) -> None:
        self.sub.set_topic(MyTopic.B)

    def pause_updates(self) -> None:
        self.sub.clear_topic()
  • set_topic(...) blocks until the running session applies the switch
  • clear_topic() disconnects the subscriber from all topics
  • topic reflects the currently active topic
  • topic switching requires the subscriber to be attached to a running session
  • signals available for UI state: switch_started, topic_changed, topic_cleared, switch_failed

Local Processing

Use ProcessorChain when widget-facing data needs ezmsg processing off the UI thread.

from ezmsg.qt import EzSession, ProcessorChain

session = EzSession()

chain = (
    ProcessorChain(MyTopic.RAW, parent=widget)
    .parallel(LowPassFilter)
    .local(ThresholdDetector)
    .connect(widget.on_processed)
    .attach(session)
)
  • .parallel(...) runs a stage group in its own sidecar process
  • .local(...) runs a stage group in the shared sidecar process
  • neither mode runs on the Qt UI thread

External Graphs

Point a session at an existing GraphRunner or GraphServer by providing graph_address.

runner.start()
session = EzSession(graph_address=runner.graph_address)
try:
    with session:
        app.exec()
finally:
    if runner.running:
        runner.stop()

API Reference

EzSession

session = EzSession(graph_address=None)
with session:
    app.exec()
  • graph_address: Optional GraphServer address
  • attach(obj): Attach an EzSubscriber, EzPublisher, or ProcessorChain
  • detach(obj): Detach an EzSubscriber or EzPublisher
  • running: Whether the session runtime is active

EzSubscriber

EzSubscriber(
    topic: Enum | str | None = None,
    parent: QObject = None,
    *,
    session: EzSession | None = None,
    leaky: bool = False,
    max_queue: int | None = None,
    throttle_hz: float | None = None,
)
  • session: The session that owns this subscriber
  • connect(slot): Connect a handler to receive messages
  • set_topic(topic): Switch to a new topic on a running session
  • clear_topic(): Unsubscribe from the current topic on a running session
  • received: Qt signal emitted when a message arrives
  • switch_started, topic_changed, topic_cleared, switch_failed: lifecycle signals for runtime switching

EzPublisher

EzPublisher(
    topic: Enum | str | None = None,
    parent: QObject = None,
    *,
    session: EzSession | None = None,
    queue_policy: QueuePolicy = "unbounded",
    max_pending: int | None = None,
)
  • session: The session that owns this publisher
  • emit(message): Send a message to the topic
  • set_topic(topic): Switch to a new topic on a running session
  • clear_topic(): Unpublish from the current topic on a running session
  • switch_started, topic_changed, topic_cleared, switch_failed: lifecycle signals for runtime switching

Installation

Install from PyPI:

pip install ezmsg-qt

You also need a Qt binding — pick one:

pip install ezmsg-qt[pyqt6]   # or
pip install ezmsg-qt[pyside6]

Or install the latest development version:

pip install git+https://github.com/ezmsg-org/ezmsg-qt@main

Development

We use uv for development.

  1. Install uv if not already installed.
  2. Fork this repository and clone your fork locally.
  3. Open a terminal and cd to the cloned folder.
  4. Run uv sync --extra pyside6 to create a .venv and install dependencies.
  5. (Optional) Install pre-commit hooks: uv run pre-commit install
  6. After making changes, run the test suite: uv run pytest tests

License

MIT License - see LICENSE for details.

Metadata

Release files for ezmsg-qt 0.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ezmsg-qt 0.2.1
File Size Uploaded
ezmsg_qt-0.2.1.tar.gz 38.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for ezmsg-qt 0.2.1
File Interpreter ABI Platform
ezmsg_qt-0.2.1-py3-none-any.whl Python 3 none any Details

Total release size: 62.5 kB

Release files / ezmsg_qt-0.2.1.tar.gz

Download URL ezmsg_qt-0.2.1.tar.gz
Size 38.7 kB
Tags Source
SHA-256 checksum
How to use checksums
114e4e887dc22627f3978c4439a3e4179cb562d79ce02df681038e52d900482d
BLAKE2b-256 checksum
How to use checksums
f680adcfdabd9cc6c6d2eb7f3eff9ef2359b41d5297b5afe56bfa4ae1135ff83
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.11.1 {"installer":{"name":"uv","version":"0.11.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / ezmsg_qt-0.2.1-py3-none-any.whl

Download URL ezmsg_qt-0.2.1-py3-none-any.whl
Size 23.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7f3013d055d8799dab7a649b2a7c7f90da7e38797dff35f05842031bcee4d153
BLAKE2b-256 checksum
How to use checksums
f5112f10136a35b3d1b8c480b08c5016a61ac090ad38b4acb0915cb5c68a818a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.11.1 {"installer":{"name":"uv","version":"0.11.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

0.2.1 This release

2 release files

0.2.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page