QtEDM Reference Manual

Robert Soliday

Updated August 2026

Advanced Photon Source

Argonne National Laboratory

Contents

Introduction

Relationship to MEDM

Requirements

Command Line

Modes of Operation

Supported Widgets

Environment Variables

ADL Files

Features

Differences from MEDM

Building QtEDM

Acknowledgments

Technical Support

Copyright

Introduction

QtEDM (Qt Editor and Display Manager) is a modern Qt5/Qt6 reimplementation of MEDM, the classic Motif Editor and Display Manager for EPICS control systems. QtEDM provides a graphical user interface for designing and operating control screens that interact with EPICS process variables through Channel Access (CA), PVAccess (PVA), and configured local data-provider plugins.

Like MEDM, QtEDM uses ADL (ASCII Display List) files to define displays. These files describe the layout, appearance, and behavior of graphical objects that present and/or modify EPICS process variables. Typical widgets include buttons, meters, sliders, text fields, strip charts, Cartesian plots, and QtEDM-specific extensions such as expression channels.

QtEDM operates in two modes:

Relationship to MEDM

QtEDM is designed as a drop-in replacement for MEDM for the standard MEDM ADL feature set. It reads and writes the same core ADL format, while also supporting a small number of QtEDM-only extensions. The primary differences are:

Both MEDM and QtEDM are built from the same source repository and share the same overall display-model lineage, which keeps the common ADL subset compatible between the two implementations while still allowing QtEDM to add new block types for QtEDM-only widgets.

Requirements

QtEDM requires the following:

QtEDM builds natively on Linux, macOS, and Windows when the platform Qt, EPICS Base, SDDS, and compiler dependencies are installed. X11 is not required for normal QtEDM operation; the -attach and -cleanup single-instance request options are available only when Qt uses the X11 xcb platform.

Command Line

QtEDM can be executed from the command line in the general form:

qtedm [options] [display-files]

Options are:

Option Description
-help, -h, -? Display usage information and exit
-version Display version information and exit
-x Start in EXECUTE mode (default is EDIT mode)
--read-only Start in EXECUTE mode with global observe-only write inhibition. A persistent red indicator is shown and all CA, PVA, and soft-PV puts are blocked and audit logged.
--session name Explicitly restore a named version-1 session. Session restore defaults to EXECUTE mode, validates every display, reports omissions, and clamps windows to connected screens.
-local Run in local mode (default)
-attach On X11, send requested displays to an existing compatible QtEDM instance
-cleanup On X11, replace stale single-instance request state and become the receiving instance
-macro "xxx=aaa,yyy=bbb,..." Define macro substitutions for PV names in EXECUTE mode
-dg geometry Specify display geometry (WxH+X+Y format)
-displayGeometry geometry Long-form alias for -dg
-displayFont alias|scalable Select font mode: alias (MEDM-compatible) or scalable
-noMsg Do not raise the message window on startup
-nolog Disable audit logging of control widget value changes
-bigMousePointer Use a larger mouse pointer for accessibility
-cmap Use a private colormap (compatibility option)

Examples

Start QtEDM with a display in execute mode:

qtedm -x main.adl

Start with macro substitutions:

qtedm -x -macro "P=ioc1:,R=motor1" motor.adl

Open multiple displays:

qtedm -x display1.adl display2.adl display3.adl

Remote Display via SSH

When running QtEDM over an SSH connection with X11 forwarding, it is highly recommended to use the -C option to enable compression. This significantly improves display update performance and provides a smoother experience, especially when monitoring rapidly changing process variables.

ssh -C -X user@host
qtedm -x display.adl

The -C option compresses all data sent over the SSH connection, which reduces the bandwidth required for X11 protocol traffic. Without compression, high-frequency widget updates can overwhelm the connection and cause sluggish or jerky display behavior.

-attach and -cleanup use an X11 root-window request protocol and fall back to local mode on Wayland, macOS, and Windows.

Modes of Operation

EDIT Mode

In EDIT mode, QtEDM functions as a display editor. You can:

The Object Palette provides access to all available widget types. Click on a widget type, then click and drag on the display to create a new widget.

EXECUTE Mode

In EXECUTE mode, QtEDM connects to EPICS and displays live process variable data. Widgets become interactive:

When QtEDM starts without -x, use the Edit/Execute selector in the main window to change modes. A command-line EXECUTE launch locks the selector for that process. Ctrl+X remains the standard Cut shortcut in EDIT mode; it is not a mode switch.

Supported Widgets

QtEDM supports the complete MEDM widget set plus QtEDM-specific extensions. The sections below expand the brief object list into a practical reference: what each widget is for, the properties that matter most, and a representative screenshot.

The screenshots in this section were captured from dedicated documentation ADL example files in docs/images/adl. Most are rendered in EDIT mode; monitor examples that need live state coloring may be captured in EXECUTE mode using local soft-PV fixtures. They are intended to show geometry, styling, labeling, and available variants in a reproducible way.

Common Widget Concepts

Graphics: Rectangle, Oval, Arc, Line, Polyline, Polygon, Text, Image, Composite

Monitors: Text Monitor, Expression Channel, Bar Monitor, Thermometer, Byte Monitor, LED Monitor, Multi-State Symbol, Heatmap, PV Table, Waveform Table, Waterfall Plot, NTNDArray Image, Scale Monitor, Meter, Strip Chart, Archive Plot, Cartesian Plot

Containers: Tabbed / Stacked Display

Controllers: Text Entry, Text Area, Slider, Wheel Switch, Choice Button, Menu, Message Button, Toggle, Spin Box, Related Display, Setpoint Control, Shell Command

Graphics

Rectangle

Rectangle widget examples in QtEDM

Rectangle examples showing filled, outlined, dashed, and dynamically visible variants.

Rectangles are the basic building block for panels, frames, alarm tiles, background fills, and simple status regions. In EXECUTE mode they are monitor-only; any behavior comes from dynamic color or visibility rules.

Oval

Oval widget examples in QtEDM

Oval examples showing circles, stretched ellipses, and outline versus filled styles.

Ovals provide circular or elliptical graphics with the same styling model as rectangles. They are commonly used for lamps, indicator bodies, and schematic symbols that should respond to process state.

Arc

Arc widget examples in QtEDM

Arc examples covering open arcs, pie-slice fills, angle ranges, and dynamic variants.

Arcs draw partial ellipses. They can be open outlines or filled wedge-style shapes and are useful for gauges, directional annotations, and process diagrams that need something more specific than a full oval.

Line

Line widget examples in QtEDM

The documentation example shows straight line segments with default and dashed styles.

Use a Line when you need a straight connection segment, pointer, or border detail. A simple line is the two-point case of the polyline data model, so line and polyline styling stay consistent.

Polyline

Polyline widget examples in QtEDM

The documentation example shows multi-segment polyline paths with default and dashed styles.

Polylines are connected line segments with arbitrarily many vertices. They are the right choice for piping runs, beam lines, and other paths that must bend without becoming filled areas.

Polygon

Polygon widget examples in QtEDM

Polygon examples showing filled and outlined multi-sided shapes across several vertex layouts.

Polygons represent closed multi-sided shapes. They are useful for arrows, custom equipment outlines, filled regions with irregular boundaries, and symbols that cannot be expressed as rectangles or ovals.

Text

Text widget examples in QtEDM

Static text examples covering alignment, font sizes, labels, and decorative uses.

Text widgets provide static labels, titles, engineering notes, and screen annotations. They are not tied to PV updates and are intended for fixed wording that helps operators interpret the rest of the display.

Image

Image widget examples in QtEDM

Image examples showing file-backed graphics, scaling, and animated/static image usage.

The Image widget displays file-backed graphics such as GIFs and other Qt image formats. It is useful for logos, equipment symbols, and any case where a drawn primitive would be too limited.

Composite

Composite widget examples in QtEDM

The graphics example includes a composite containing child widgets that move and render as one object.

A Composite groups multiple child widgets into a single higher-level object. This is useful when a display repeatedly reuses the same local assembly of labels, indicators, and controls.

Monitors

Text Monitor

Text Monitor widget examples in QtEDM

Text Monitor examples showing numeric formatting, string readback, alignment, and alarm-driven color changes.

Text Monitor is the standard readback widget for scalar or string PVs. It displays the current value as text and can format the value for operator readability without allowing writes.

Expression Channel

Expression Channel is a QtEDM-only logical monitor widget that evaluates an EPICS calc expression over up to four input channels and publishes the result as a process-local soft PV. In EDIT mode it appears as a compact labeled rectangle so it can be selected and configured. In EXECUTE mode it becomes invisible and runs only as a calculation/publishing node.

Bar Monitor

Bar Monitor widget examples in QtEDM

Bar Monitor examples covering horizontal and vertical bars, different scales, and color modes.

Bar Monitor turns a scalar PV into a filled bar graph. It is one of the clearest ways to show level, percentage, position, or any value that should be interpreted relative to a range.

Thermometer

Thermometer widget examples in QtEDM

Thermometer examples showing vertical fill, value overlays, and several limit configurations.

Thermometer is a QtEDM-only monitor widget that presents a scalar PV as a thermometer-style fill. It provides a more literal physical metaphor than a generic bar graph.

Byte Monitor

Byte Monitor widget examples in QtEDM

Byte Monitor examples displaying individual bits and grouped status patterns from integer PVs.

Byte Monitor breaks an integer PV into visible bit states. It is especially useful for status words, interlocks, mode fields, and hardware flags where individual bits are meaningful to operators.

LED Monitor

LED Monitor widget examples in QtEDM

LED Monitor examples showing a static lamp, an alarm-driven indicator, and a discrete multi-state indicator.

LED Monitor is a QtEDM-only compact status lamp. It is intended for cases where a single small shape should communicate connection, alarm state, or a discrete integer state more directly than a full bar, meter, or layered graphic composite.

Property Purpose
channel The PV or soft-PV driving the LED state.
colorMode static, alarm, or discrete.
shape circle, square, or rounded_square.
bezel Enables the lamp-style raised ring and highlight.
onColor / offColor Convenience colors for binary-style usage and edit-mode previews.
undefinedColor Fallback color for disconnects or out-of-range discrete states.
stateCount / stateColorN Configures the discrete color table for integer states 0 through 15.
visibilityMode, visibilityCalc, visibility channels Optional hide/show behavior matching the other dynamic widgets.
led_monitor {
  object {
    x=60
    y=110
    width=24
    height=24
  }
  monitor {
    chan="device:state"
    clr=25
    bclr=4
  }
  colorMode="discrete"
  shape="rounded_square"
  bezel=1
  stateCount=4
  stateColor0=12
  stateColor1=15
  stateColor2=33
  stateColor3=20
  undefinedColor=7
}

Multi-State Symbol

Multi-State Symbol is a QtEDM extension stored as qtedm_symbol. It maps numeric values or inclusive ranges to a color, label, and optional image. Undefined values and disconnected channels remain visibly hatched, while active alarms add a severity-colored border.

Tabbed Display

Tabbed Display is a QtEDM extension stored as qtedm_tabbed_display. Each page has a stable ID, label, file-backed child ADL, page macros, and a keepAlive policy. Page macros override inherited parent macros.

Heatmap

Heatmap widget example in QtEDM

Heatmap example showing the widget layout with title area, plot area, and optional profile regions.

Heatmap is a QtEDM-only 2-D array monitor. It renders a waveform or array PV as a color image and can derive the X and Y dimensions from either fixed values or additional PVs.

PV Table

PV Table is a QtEDM-only read-only monitor for a small list of related PVs. Each configured row subscribes independently and can show the row label, PV name, current value, engineering units, and alarm severity in a single compact table.

Property Description
columnsComma-separated subset of label, pv, value, units, and severity.
colorModestatic or alarm foreground coloring.
showHeadersShows or hides the table column headers.
fontSizeManual table font size using MEDM legacy font-size units. In alias font mode, QtEDM uses the nearest larger MEDM alias when available and falls back to a scalable font for larger requested sizes.
rowOne table row with a label and monitored chan.

Example ADL fragment:

pv_table {
  object { x=40 y=80 width=620 height=160 }
  "basic attribute" {
    clr=14
    bclr=4
  }
  colorMode="alarm"
  showHeaders=1
  fontSize=12
  columns="label,pv,value,units,severity"
  row {
    label="Beam Current"
    chan="BPM:CURRENT"
  }
  row {
    label="Mode"
    chan="BPM:MODE"
  }
}

Waveform Table

Waveform Table is a QtEDM-only read-only table monitor for a single waveform or array PV. It is intended for exact sample inspection: operators can see the current element values, indexes, connection state, received length, and alarm-driven foreground color without turning the waveform into a plot.

Property Description
chanWaveform, array, or scalar fallback PV to monitor.
layoutgrid, row, or column sample arrangement.
columnsGrid column count. Column layout always shows Index and Value columns.
fontSizeManual table font size using MEDM legacy font-size units. In alias font mode, QtEDM uses the nearest larger MEDM alias when available and falls back to a scalable font for larger requested sizes.
maxElementsMaximum displayed samples. A value of zero allows the runtime default limit.
indexBaseIndex labels start at zero or one.
valueFormatdefault, fixed, scientific, hex, or engineering numeric formatting.
charModestring, bytes, ascii, or numeric display for char waveforms.

Example ADL fragment:

wave_table {
  object { x=40 y=80 width=520 height=220 }
  "basic attribute" {
    clr=14
    bclr=4
  }
  chan="BPM:WAVEFORM"
  colorMode="alarm"
  showHeaders=1
  fontSize=12
  layout="grid"
  columns=8
  maxElements=256
  indexBase=0
  valueFormat="default"
  charMode="string"
}

Waterfall Plot

Waterfall Plot widget in QtEDM connected to a waveform PV

Waterfall Plot connected to a waveform PV, showing successive buffered samples rendered as a scrolling intensity image with a legend.

Waterfall Plot is a QtEDM-only monitor for waveform-versus-time data. It sits between Cartesian Plot, which shows the current waveform as traces, and Heatmap, which renders a single 2-D array. Each new waveform becomes one time slice in the rolling buffer.

Property Description
dataChannelWaveform PV. Each monitor update adds one sample to the waterfall.
countChannelOptional PV supplying the active waveform length when the array is only partially populated.
triggerChannelOptional PV used to trigger sampling of the most recent waveform update.
eraseChannelOptional PV used to clear the rolling buffer when the configured erase transition occurs.
eraseModeControls whether a zero or non-zero transition clears the buffer.
title, xLabel, yLabelPlot title and axis labels.
historyCountNumber of waveform samples retained in the rolling buffer.
scrollDirectionChooses where new samples appear: top, bottom, left, or right.
colorMap, invertGreyscaleIntensity palette selection, reusing the Heatmap color maps.
intensityScale, intensityMin, intensityMaxAuto, manual, or logarithmic intensity scaling for the image and legend.
showLegend, showGridOptional legend bar and faint axis grid overlay.
samplePeriod, unitsOptional fixed sample spacing used for time-axis labeling and data export when timestamps are not available.
foreground, backgroundColors used for labels, axes, and the plot background.

Example ADL fragment:

waterfall_plot {
  object { x=40 y=40 width=320 height=220 }
  plotcom {
    title="Beam Profile vs Time"
    xlabel="Position (mm)"
    ylabel="Time (s)"
    clr=14
    bclr=0
  }
  data { chan="BPM:WAVEFORM" }
  count { chan="BPM:NUSE" }
  trigger { chan="BPM:TRIG" }
  erase { chan="BPM:ERASE" mode="ifnotzero" }
  historyCount=200
  scrollDirection="topToBottom"
  colorMap="rainbow"
  intensityScale="auto"
  showLegend=1
  showGrid=0
  samplePeriod=0
  units="seconds"
}

Right-clicking a Waterfall Plot in EXECUTE mode adds Save Image..., Save Data..., Clear Buffer, and Reset Zoom when zoom is active.

Scale Monitor

Scale Monitor widget examples in QtEDM

Scale Monitor examples showing pointer direction, labels, and mixed geometry ranging from tiny to large.

Scale Monitor is a compact analog-style readback widget combining a ruler, tick marks, and a moving indicator. It works well when a bar monitor feels too heavy but text alone is not visual enough.

Meter

Meter widget examples in QtEDM

Meter examples showing analog needle displays, scale labeling, and size-dependent layout.

Meter presents a scalar PV as an analog dial. It is useful for displays that benefit from a familiar instrument-panel look or when operators prefer to recognize direction and magnitude from needle position.

Strip Chart

Strip Chart widget examples in QtEDM

Strip Chart examples showing multi-trace time histories, axes, and chart layout variations.

Strip Chart trends one or more PVs against time. It is the standard widget for short-term history, quick diagnostics, and operator displays that need to show whether a signal is stable, drifting, or oscillating.

Archive Plot

Archive Plot is a QtEDM-only historical variant of Strip Chart stored as qtedm_archive_plot. On entering EXECUTE mode it requests each configured pen's current time window from the selected archive provider and continues subscribing to the live PV.

Cartesian Plot

Cartesian Plot widget examples in QtEDM

Cartesian Plot examples with multiple traces, axis combinations, scatter-style displays, and overlaid lines.

Cartesian Plot is the most flexible plotting widget in QtEDM. It can show Y-only traces against sample index or true X-Y data, and it supports multiple traces with independent axis assignments.

QtEDM-only note: Heatmaps, waterfall and archive plots, tables, symbols, tabbed displays, expression channels, and the other QtEDM extensions in this section use additional ADL block types. Legacy MEDM can continue to use the shared core subset, but it does not provide runtime support for QtEDM-only blocks. See ADL Files for the complete extension list.

Controllers

Text Entry

Text Entry widget examples in QtEDM

Text Entry examples showing editable numeric and string fields with different sizes and color modes.

Text Entry allows an operator to type a value and write it to a PV. It is the most direct control widget when precise numeric or string input matters more than constrained stepwise adjustment.

Text Area

Text Area is the multi-line companion to Text Entry. It is intended for long strings and waveform-backed text, preserving embedded line breaks while still allowing operator edits in EXECUTE mode.

Slider

Slider widget examples in QtEDM

Slider examples showing horizontal and vertical layouts, label regions, and value ranges.

Slider provides a drag-based numeric control. It is well suited to setpoints and analog adjustments where the operator thinks in terms of moving a value within a bounded range.

Wheel Switch

Wheel Switch widget examples in QtEDM

Wheel Switch examples showing digit-by-digit editing across different widths and precisions.

Wheel Switch is a precision numeric entry widget in which each digit can be incremented or decremented independently. It is ideal for control rooms where operators want explicit control over significant digits.

Choice Button

Choice Button widget examples in QtEDM

Choice Button examples with discrete states rendered as always-visible buttons in several styles.

Choice Button presents a small fixed set of states as visible buttons rather than hiding them in a drop-down. It is most useful for enum-like PVs where the operator should always see the available choices.

Menu

Menu widget examples in QtEDM

Menu examples showing compact drop-down selection for enumerated and discrete values.

Menu is the compact alternative to Choice Button. It exposes the current value in a drop-down control and is appropriate when the state list is longer or screen real estate is limited.

Message Button

Message Button widget examples in QtEDM

Message Button examples showing command-style controls with different labels and value mappings.

Message Button writes a predefined value when activated. It is the right widget for command actions such as Start, Stop, Reset, Open, Close, or acknowledgement operations.

Toggle

Toggle is a compact two-state QtEDM control stored as qtedm_toggle. It follows the current PV value, writes explicit on/off values, uses independent state labels, and can require confirmation before each write. Scalar, enum, string, and character-array targets use the same typed write path as Message Button.

Common colors, channel, and values are editable through the resource palette. State labels and confirmation are available through QtEDM Extension Properties....

Spin Box

Spin Box is a bounded numeric QtEDM control stored as qtedm_spinbox. It adds autorepeating decrement and increment buttons to the existing setpoint implementation and therefore inherits PV control limits, precision, engineering units, alarm color, connection state, access rights, and audit logging. The step size is edited with QtEDM Extension Properties....

Setpoint Control

Setpoint Control is a QtEDM-only numeric controller stored as setpoint_control. It combines an editable setpoint, optional readback, and an in/out-of-tolerance indication in one widget.

setpoint_control {
  object {
    x=40 y=40 width=300 height=54
  }
  "basic attribute" {
    clr=14 bclr=4
  }
  label="Temperature"
  setpoint="HEATER:SP"
  readback="HEATER:RBV"
  colorMode="alarm"
  toleranceMode="absolute"
  tolerance=0.5
}

Related Display

Related Display widget examples in QtEDM

Related Display examples showing buttons that open additional ADL screens with operator-friendly labels.

Related Display is a navigation widget rather than a direct PV writer. It opens one or more ADL files and can pass macro substitutions so downstream displays inherit the current device or subsystem context.

Shell Command

Shell Command widget examples in QtEDM

Shell Command examples showing command-launch buttons with multiple labels and action rows.

Shell Command launches external commands from a display button. It is useful for opening helper tools, diagnostic scripts, or file viewers that sit outside the ADL display itself.

Environment Variables

QtEDM uses the following environment variables:

Variable Description
EPICS_DISPLAY_PATH Platform-separated list of directories to search for ADL files and referenced images (: on Unix, ; on Windows)
EPICS_CA_ADDR_LIST EPICS Channel Access address list
EPICS_CA_AUTO_ADDR_LIST Enable/disable automatic CA address discovery
QTEDM_AUDIT_DIR Optional audit-log directory override. The default remains ~/.medm.
QTEDM_ARCHIVER_URL EPICS Archiver Appliance retrieval root used by archive-backed plots.
QTEDM_ARCHIVER_PROVIDER Archive-provider plugin ID. Empty or archiver-appliance selects the built-in provider.
QTEDM_PLUGIN_PATH Platform-separated list of absolute local plugin directories. QtEDM also scans the plugins directory next to its executable.
QTEDM_NOLOG Set to a non-empty value other than 0 to disable control-write audit logging. Equivalent to -nolog.
MEDM_EXEC_LIST MEDM-compatible semicolon-delimited entries added to the EXECUTE-mode context menu. Each item supplies a label and command.
QTEDM_TIMING_DIAGNOSTICS Set to a non-empty value other than 0 to print timestamped startup-phase timing to standard error.
TRACK_MEM Diagnostic memory sampling in the form [interval][:logfile]; the interval defaults to 60 seconds and output defaults to standard error.

Standard EPICS CA and PVA environment variables are consumed by EPICS Base. Diagnostic variables are intended for troubleshooting, not routine operator configuration. Automated tests also use private QTEDM_TEST_* variables; those are test interfaces and are intentionally not part of the supported operator configuration surface.

ADL Files

ADL (ASCII Display List) files are text files that describe display layouts. QtEDM uses the same core ADL format as MEDM and extends it with a small number of QtEDM-only block types when a display uses QtEDM-specific widgets.

An ADL file contains:

QtEDM reads ADL files created by MEDM. MEDM can read the common ADL subset written by QtEDM, but displays that use QtEDM-only extensions are not behaviorally compatible with legacy MEDM. The common file format is documented in the MEDM Reference Manual.

PV Protocol Prefix

QtEDM supports both Channel Access (CA) and PVAccess (PVA). To force PVA for a specific channel, prefix the PV name with pva://:

ADL Version Header

QtEDM writes a file header version of 40001 when any PV uses the pva:// prefix. Displays with only CA PVs are saved with version 40000. Both versions remain fully readable by QtEDM.

QtEDM-only ADL Extensions

QtEDM currently adds these object and attached-rule block types beyond the legacy MEDM set:

Display Import

File → Import Display... converts a caQtDM or Qt Designer .ui file into ADL. The same reusable converter is available as qtedm-convert. The source file is preserved, tab pages become file-backed child ADLs, and a versioned JSON report classifies every source object as mapped, approximated, omitted, or unsupported. Unsupported objects remain visible as labeled placeholders. Command-line exit status is 0 for a complete mapping, 2 for a completed conversion with warnings, and 1 for fatal failure.

qtedm-convert [--output display.adl] [--report report.json]
              [--source-copy preserved.source.ui] input.ui

-o is accepted as an alias for --output. With no output options, screen.ui produces screen.adl, screen.qtedm-conversion.json, and screen.source.ui beside the input. Input, output, report, and preserved-source paths must be distinct. Version 1 accepts one .ui input up to 64 MiB.

NTNDArray Image

NTNDArray Image is a QtEDM extension stored as qtedm_ndarray_image. It subscribes to a structured raw epics:nt/NTNDArray using an explicit pva:// channel and retains the typed data and dimensions.

Version 1 Local Plugins

QtEDM can load trusted local Qt plugins for custom display objects, data provider URI schemes, and archive providers. A plugin library must be installed with a versioned .qtedm-plugin.json sidecar in the executable's plugins directory or an absolute directory from QTEDM_PLUGIN_PATH. Remote plugin loading is not supported.

The loader requires the exact Qt major version, build architecture, compiler ABI, and QtEDM interface version. It also rejects duplicate plugin IDs, display type IDs, data schemes, and archive-provider IDs. Missing or incompatible display plugins appear as labeled placeholders, and their original qtedm_plugin nodes remain intact when the display is saved.

Plugin data-provider and display-widget writes pass through QtEDM's central write policy, so observe-only mode and auditing apply before the provider sees a put. See docs/QtEDM_Plugin_API.md in the source distribution for the complete interface, metadata, lifecycle, and packaging contract.

Declarative Property Rules

Select a built-in or plugin widget in EDIT mode and choose Declarative Property Rules... to attach a qtedm_rules block. Rules reuse the EPICS calculation grammar with typed inputs A through L. They may change only visibility, enabled state, text, foreground/background color, or geometry.

Each rule has a 1–60 Hz evaluation cap and explicit disconnect behavior. QtEDM detects duplicate IDs and dependency cycles, reports authoring errors, and restores original properties when EXECUTE mode ends. Version 1 is not a script engine: Python, JavaScript, filesystem access, process execution, network access, and PV writes are unavailable and rejected by validation.

Named Sessions

File → Save Session... stores the current top-level display paths, macros, window geometries, screen names, active tab IDs, and edit/execute state in a versioned JSON file below QStandardPaths::AppConfigLocation/sessions. Restore is always explicit: use File → Restore Session... or --session name. QtEDM never silently restores a prior layout.

Restore opens valid displays in EXECUTE mode, reports missing or renamed files and invalid records, and moves off-screen or oversized windows onto an available screen. A changed or missing active tab falls back to the display's configured default.

The expression_channel block stores a local calc node that publishes a soft PV for other widgets to consume. A typical block looks like this:

expression_channel {
  object {
    x=20
    y=66
    width=120
    height=40
  }
  variable="expr:sum"
  calc="A+B"
  channelA="src:pv1"
  channelB="src:pv2"
  channelC=""
  channelD=""
  initialValue=0
  eventSignal="onAnyChange"
  clr=30
  bclr=4
  precision=3
}

Expression-channel outputs are process-local to the running QtEDM instance. Other widgets subscribe to the result by using the variable value as their ordinary channel name.

PV Snapshots

File → Save PV Snapshot... captures the deduplicated channels used by the active display into a version-1 .qtedm-snapshot.json file. Scalar numeric, string, enum, character array, and numeric-array values retain provider, exact type, timestamp, units, limits, connection state, access state, and enum metadata. Capture warnings are reported instead of silently inventing unavailable values.

File → Compare / Restore PV Snapshot... first shows saved and current values side by side. Nothing is selected by default. Rows are eligible only when the current PV is connected and writable and its provider, exact type, value kind, enum choices, and limits remain compatible. After the user selects rows, QtEDM asks for confirmation and repeats every safety check immediately before each write.

Observe-only mode blocks restore, string-array restore is unsupported, and file, entry, and array sizes are bounded. Successful and failed restore attempts are audit logged. Snapshot files are local operational artifacts; review their contents and storage permissions before using them to change live equipment.

Features

Dynamic Attributes

Graphics widgets support dynamic attributes that change appearance based on PV values:

Macro Substitution

PV names can include macro references like $(P) that are replaced at runtime. This allows creating reusable displays that work with different devices.

Local Plugins and Property Rules

Reviewed facility plugins can add display types and CA/PVA-adjacent data or archive providers without changing the QtEDM executable. Declarative property rules provide a separate sandboxed path for display-author logic when a native plugin is unnecessary. Both mechanisms preserve unknown ADL extension data so a temporarily missing plugin does not destroy a display.

Related Displays

Related Display widgets can open additional displays, optionally passing macro substitutions and replacing or overlaying the current display.

Expression Channels and Soft PVs

QtEDM provides expression channels as a built-in local-logic feature. An expression channel evaluates an EPICS calc expression over up to four input channels and publishes the result as a named soft PV inside the QtEDM process.

Printing

Displays can be printed using the File > Print menu. Page setup options allow configuring paper size and orientation.

PV Information

Right-click on a widget in EXECUTE mode to access PV information including connection status, current value, alarm limits, and access rights.

Differences from MEDM

QtEDM preserves the standard MEDM ADL subset, with these intentional differences and additions:

Building QtEDM

QtEDM is built as part of the MEDM source distribution. From the repository root:

make -j4

This builds QtEDM and qtedm-convert; it also builds MEDM when Motif/X11 development files are available. Programs are copied to bin/<OS>-<architecture>/, for example bin/Linux-x86_64/qtedm.

On a clean tree, a full build can take several minutes. If you are trying to diagnose a warning or an error and want less interleaved output, rerun the same build without -j4.

Build requirements:

On non-Windows platforms the build system prefers Qt6 when its pkg-config modules are present and otherwise falls back to Qt5. See the repository README.md for dependency layout and platform-specific notes.

From the repository root, make test-qtedm runs CLI, unit, IOC, and visual regression suites. The narrower targets are test-qtedm-cli, test-qtedm-unit, test-qtedm-ioc, and test-qtedm-visual.

Acknowledgments

QtEDM builds upon the foundation laid by the original MEDM developers:

QtEDM was developed by Robert Soliday at Argonne National Laboratory as a modern alternative to the Motif-based MEDM, ensuring continued support for EPICS display management on contemporary Linux, macOS, and Windows systems.

The EPICS community has contributed numerous bug fixes, platform ports, and suggestions that have improved both MEDM and QtEDM.

Technical Support

If you have problems, comments, or questions about QtEDM you can send them to soliday@anl.gov. If you wish to report a bug, it is essential that you send enough information for the bug to be reproduced. It would be helpful to include:

Another source of help is the EPICS Tech-Talk forum at https://epics.anl.gov/tech-talk/index.php. This page includes an archive of articles and directions for joining the forum. You may present your problem and often get practical responses from the many users of EPICS.

Copyright

Copyright © 2002 The University of Chicago, as Operator of Argonne National Laboratory.

Copyright © 2002 The Regents of the University of California, as Operator of Los Alamos National Laboratory.

QtEDM is distributed subject to a Software License Agreement found in the file LICENSE that is included with the distribution.

EPICS and Channel Access are trademarks of the University of Chicago.