Database Manual · Chapter 8

Button Events — ViewRun Handlers

Every user action in the sample starts at ViewRun.xms's six click handlers. Each handler is a one-liner that calls into a Data:: module function — keeping business logic and UI events cleanly separated.

ViewRun (UI events)            Data (DB business logic)
─────────────────────────      ──────────────────────────
OnOpenClick    ───►           DB_Open()
OnAddClick     ───►           DB_InsertSample()
OnUpdateClick  ───►           DB_UpdateSelected()
OnModifyClick  ───►           DB_OpenModifyDlg() ──► GUI.ShowDialog → DB_UpdateModified()
OnDeleteClick  ───►           DB_DeleteSelected()
OnCloseClick   ───►           DB_Close()

1) Standard handler signature

QMachineStudio's click handlers all share the same signature.

FUNCTION OnXxxClick(string sender, int tag, array params)
{
   // sender : button control's name
   // tag    : value of the button's Tag property (for branching)
   // params : extra args (mostly unused)
 
   Data::DB_Xxx();
}

The sample's six handlers are all one-line wrappers around Data:: functions.

FUNCTION OnOpenClick   (string sender, int tag, array params) { Data::DB_Open();             }
FUNCTION OnAddClick    (string sender, int tag, array params) { Data::DB_InsertSample();     }
FUNCTION OnUpdateClick (string sender, int tag, array params) { Data::DB_UpdateSelected();   }
FUNCTION OnModifyClick (string sender, int tag, array params) { Data::DB_OpenModifyDlg();    }
FUNCTION OnDeleteClick (string sender, int tag, array params) { Data::DB_DeleteSelected();   }
FUNCTION OnCloseClick  (string sender, int tag, array params) { Data::DB_Close();            }

What this separation buys you:

  • Test the DB functions on their own — no UI required.
  • The same function can be reused from another screen (ViewMain) or a sequence.
  • During debugging it's instantly clear whether the issue is in the event side or the DB side.

2) Wiring buttons to handlers

In ViewRun's design mode, set each button's Click event → Function name like so.

Button (caption)Control nameClick event function
OpenBtnOpenOnOpenClick
AddBtnAddOnAddClick
UpdateBtnUpdateOnUpdateClick
ModifyBtnModifyOnModifyClick
DeleteBtnDeleteOnDeleteClick
CloseBtnCloseOnCloseClick

The (sender, tag, params) parameters are received but ignored in the body. They become useful only if multiple buttons share a handler and branch on tag.


3) ModifyDlg flow — two-step call

Modify is the only button that involves a modal dialog plus result branching. The actual branching lives inside Data::DB_OpenModifyDlg(), so the ViewRun side is still one line.

[Modify clicked]


ViewRun.OnModifyClick


Data.DB_OpenModifyDlg

       ├─ 1. SELECTed row → copied into Edit* fields
       ├─ 2. GUI.ShowDialog("ModifyDlg")
       │      │
       │      ├─ true  (OK)     ──► DB_UpdateModified() → DB_Refresh()
       │      └─ false (Cancel) ──► return


    return

GUI.ShowDialog blocks at the call site — the next line doesn't run until the dialog closes. So OnModifyClick's one-line call returns only after the user clicks OK or Cancel.

Dialog-side events

ModifyDlg.xms itself contains no business logic — only diagnostic logs.

FUNCTION OnShow()
{
   // Right before showing - edit fields are already populated by the caller
   Log($"ModifyDlg OnShow : id={Data::EditId} order_no={Data::EditOrderNo}");
}
 
FUNCTION OnHide()
{
   // Right after closing
}

The OK / Cancel buttons just set DialogResult; the actual UPDATE happens in the caller's DB_OpenModifyDlg which branches on ShowDialog's return value. The dialog never has to know its own business logic — great for reuse.


4) Relation to Init / Mon / Event

The sample also ships these modules — not strictly DB-related, but worth a brief mention since they're standard structure for any automation project.

ModuleTypeUse
InitInitRuns once on boot — data init, tower-lamp setup
MonMonitorPeriodic monitoring — door / IO / safety
EventEventReceives events (network, external signals)
DataMonitorStar of this tutorial — DB functions live here
WorkSequenceMain sequence (no DB involvement)

DB work lives in Data to keep it separated from the equipment sequence (Work). The sequence has to keep running even if the DB hiccups, and it just calls Data::DB_* functions.

Next Chapter

Time for backup and operations — WAL mode, BackupFolder, auto backup options.