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:
| Approach | Best For | Editor |
|---|---|---|
| Visual flow | Most cases: calling device actions, writing variables, showing toasts, simple conditions | Drag-and-drop sequence editor, no coding required |
| Code script | Complex algorithms, type conversion, error handling | Code editor (TypeScript) |
Prefer visual flows. 90% of field scenarios are covered by sequential device calls, variable writes, and toast messages.
Creating Actions
- In the page properties panel, under "Methods", click the + button.
- Enter the action name and choose the type.
- 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
- In the left resource panel, under Components, right-click to create.
- Place widgets inside the component editor tab.
- Define props (the data fields passed in from outside).
- Use
samplePropsto 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 inputself.state— internal component stateself.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.