Skip to main content

Pages & Components

Pages are on-site HMI screens. Widgets are elements on the screen — buttons, indicators, data tables, 3D models, etc. Widgets trigger backend logic through event actions.

For specific widget parameters and usage, refer to the property panel in the editor. This document covers concepts and key mechanisms only.

Event Actions (Page Methods)

Widget events (button clicks, table changes, upload completion) trigger action logic. Two approaches are available:

ApproachBest ForEditor
Visual flowMost cases: calling device actions, writing variables, showing toasts, simple conditionsDrag-and-drop sequence editor, no coding required
Code scriptComplex algorithms, type conversion, error handlingCode editor (TypeScript)

Prefer visual flows. 90% of field scenarios are covered by sequential device calls, variable writes, and toast messages.

Creating Actions

  1. In the page properties panel, under "Methods", click the + button.
  2. Enter the action name and choose the type.
  3. After creation, bind it in a widget's action property.

Visual Flow Editing

Flow actions are edited in the WorkArea's Sequence tab:

  • Input parameters: Values passed in externally (e.g., current widget ID, row data)
  • Step sequence: Actions executed in order
  • Return value: Output after execution

Supported step types: call device methods, call queries, write variables, show toasts, conditionals, loops.

Pass results between steps with steps.<stepName>.result.

Screenshot placeholder: Visual flow editor

Code Scripts

Use TypeScript for cases requiring complex logic:

function handleStart() {
const axis = QX.objects.ZAxis;
const result = axis.home();
if (result.ok) {
QX.variables.homingStatus = 'done';
}
}

The editor provides intelligent suggestions and error checking, indicating whether referenced devices, variables, and methods exist.

Binding Actions to Widgets

A widget's action property supports two binding styles:

  • Direct method name: "handleStart" — the action receives the full event context
  • Parameterized binding: { method: "handleStart", args: { axisId: "context.widget.id" } } — maps event data to explicit parameters

The second form is recommended for clearer semantics.

Expression Binding

Most widget properties support {{ }} expressions for dynamic binding to variables, object states, and query results. Examples:

  • Variable binding: {{ QX.variables.currentTemperature }}°C
  • Object state: {{ QX.objects.PulsarController.status }}
  • Visibility control: {{ QX.variables.isRunning }} determines whether a button is disabled

Switch to script mode in the property panel and click the reference button to browse available fields in context.

Reusable Components

Encapsulate a group of widgets into a template for reuse in repeaters. For example, a station card containing a label, status indicator, and output counter — built once as a component, reused across multiple stations.

Creating Components

  1. In the left resource panel, under Components, right-click to create.
  2. Place widgets inside the component editor tab.
  3. Define props (the data fields passed in from outside).
  4. Use sampleProps to preview rendering with different data.

Working with Data in Components

  • Access repeater data directly via field names (e.g., item, index)
  • self.props — complete external input
  • self.state — internal component state
  • self.widgets — child widgets within the component

Each repeater item's component instance is fully isolated.

Permission Control

Both pages and widgets can have visibility restricted by role. See Users & Roles.