Files
eco/docs/live_gui.md
Henrik Lemke 98d8e4a0c5 docs: "Did you know?" tips, pages for recent features, and a docs-site job
- docs/did_you_know/: one short tip per feature added since May 2026
  (<date>-<slug>.md, YAML front matter: added/tags/details), listed
  newest first; index.md describes the format for adding more.
- New pages for features that had none: launching, command_history,
  tab_completion, live_gui, tweak, scanning, status_server,
  channel_access, shared_files, schematic_panels. Wired into index.rst
  together with the existing queues page.
- Fix archiver_stripchart/listening_monitor: the method is
  archiver.strip_plot (strip_chart does not exist on DataHub); document
  the per-device .strip_plot().
- NAMESPACE_MONITOR_FORMAT.md: scan monitoring is wired into Daq's scan
  callbacks since 2026-09-09.
- scripts/eco-docs (+ -install-user-service): build the docs from an own
  clone and serve them over HTTP as user systemd units, rebuilt by a
  timer; a failed build never replaces the served site.
2026-10-25 14:26:52 +01:00

2.1 KiB
Raw Permalink Blame History

GUI windows stay live while a command runs

Qt windows (camera viewers, live plots, strip charts in-process, the desktop workbench itself) can only be redrawn by the main Python thread. IPython normally redraws them only while it waits at the prompt. So, traditionally, a blocking statement froze every open window until it returned: umv, a scan, time.sleep, a long loop.

eco now keeps those windows serviced during such statements:

cam_north.widget()       # open a live camera viewer
umv(mot, 10)             # the viewer keeps updating while the motor moves

Measured on a 20 Hz camera viewer during sleep, a motor wait() and pure Python loops: before, 0 frames/s; now, 19–20 frames/s. That holds both in a terminal session and docked in the desktop. In the desktop it also keeps the console itself responsive, so Ctrl-C / Interrupt reaches a running cell.

This is also why camera viewers now open in-process by default: they start instantly, dock into the desktop, and share the very camera object your session uses.

How it works

A watchdog thread notices when Qt's own event loop has not run for 60 ms while a cell is executing. It then briefly interrupts the main thread to process pending GUI events, after which your code continues where it was. When Qt's loop runs by itself (at the prompt), nothing happens at all.

Checking and switching it off

from eco.utilities import mainthread
mainthread.status()          # what it has been doing
ECO_NO_HEARTBEAT=1 eco        # start a session without it

Limits

  • A single long call into C code on the main thread (a large numpy operation, for example) cannot be interrupted. The windows resume when it returns.
  • A Ctrl-C that arrives while the GUI is being serviced is held back for that moment and then raised in your code, as usual.
  • For developers: an untimed wait on the main thread (thread.join(), event.wait() without a timeout) cannot be interrupted either. Use mainthread.join(thread) / mainthread.wait_event(event), which wait in slices. eco's own waits (Changer.wait(), Acquisition.wait(), a paused scan) already do.