画面绑定
示例画面分为两部分。
| 画面 | 角色 | 核心绑定 |
|---|---|---|
| ViewRun | 主画面 — DataGrid + 6 按钮 | Data::DispData(行数组)· Data::SelectIndex(选中索引) |
| ModifyDlg | 记录修改对话框 | Data::EditId · EditOrderNo · EditMenuName · EditEndTime 等 8 个 |
脚本只更新数据(array DispData[]、int EditWeightG 等),控件会自动按数据重绘 — 这一连线正是本章的核心。
1) ViewRun · XDataGrid 绑定
Data.xms 声明了下面两个变量。
// CSV 1 行 = 1 行 (id,order_no,menu_name,start_time,end_time,weight_g,result,is_error)
array DispData[] = {"",};
// XDataGrid 自动更新当前选中行索引(-1 = 未选中)
int SelectIndex = -1;在 XDataGrid 控件的 Property Editor 中,如下设置两个属性:
| 属性 | 值 | 含义 |
|---|---|---|
| ItemsSourceDataName | Data::DispData | 数据网格显示的行数组 |
| SelectIndexDataName | Data::SelectIndex | 用户选行时该变量记为 0..N-1,未选为 -1 |
CSV 行格式
DispData 的一个元素是用逗号拼接的一行字符串。
"42,O1042,Latte,2026-05-06 09:31:02,2026-05-06 09:31:30,300,Done,0"DB_Refresh() 末尾正是直接用 GetRowArray(i) 的结果按此格式拼接并填充。
Columns 定义
DataGrid 的 Columns 属性中定义对应的 8 列后,CSV 第 N 个字段会自动映射到第 N 列。
| 索引 | Header | 推荐 Format / Width |
|---|---|---|
| 0 | id | width 60 |
| 1 | order_no | width 90 |
| 2 | menu_name | width 120 |
| 3 | start_time | width 160 |
| 4 | end_time | width 160 |
| 5 | weight_g | format 0.0,width 80 |
| 6 | result | width 80 |
| 7 | is_error | width 60 |
刷新流程
脚本只做 DispData.Clear() → 反复 Add() 即可。DB_Refresh() 中拼好的每一行依次进入 DispData,画面自动重绘。
DispData.Clear();
for( i, 0, rows-1 )
{
array row = DB["local"].GetRowArray(i);
DispData.Add($"{row[0]},{row[1]},{row[2]},{row[3]},{row[4]},{row[5]},{row[6]},{row[7]}");
}2) ModifyDlg — 对话框 + 双向绑定
ModifyDlg 是 ViewModule type 为 Dialog 的画面。
8 个编辑字段
Data.xms 中声明的变量与对话框的输入控件 1:1 绑定。
// Data.xms 摘录
int EditId = 0; // PK(只读显示)
string EditOrderNo = "";
string EditMenuName = "";
string EditStartTime = ""; // 只读显示
string EditEndTime = "";
double EditWeightG = 0.0;
string EditResult = "";
int EditIsError = 0;将对话框中各 XTextBox / XNumberBox / XCheckBox 的 DataName 属性设为这些变量名,用户输入便会自动回写到 Data::Edit*。
| 对话框控件 | DataName | 建议只读 |
|---|---|---|
| Id 显示 | Data::EditId | ✓ |
| Order No 输入 | Data::EditOrderNo | |
| Menu 输入 | Data::EditMenuName | |
| Start time | Data::EditStartTime | ✓ |
| End time | Data::EditEndTime | |
| Weight (g) | Data::EditWeightG | |
| Result | Data::EditResult | |
| Error 复选框 | Data::EditIsError |
对话框调用流程
Modify 按钮调用的 DB_OpenModifyDlg() 是标准模式。
FUNCTION DB_OpenModifyDlg()
{
// (省略守卫)
// 1) 把选中行的值复制到编辑字段
EditId = DB["local"].GetValueInt(SelectIndex, "id");
EditOrderNo = DB["local"].GetValue (SelectIndex, "order_no");
EditMenuName = DB["local"].GetValue (SelectIndex, "menu_name");
EditStartTime = DB["local"].GetValue (SelectIndex, "start_time");
EditEndTime = DB["local"].GetValue (SelectIndex, "end_time");
EditWeightG = DB["local"].GetValueDouble(SelectIndex, "weight_g");
EditResult = DB["local"].GetValue (SelectIndex, "result");
EditIsError = DB["local"].GetValueInt(SelectIndex, "is_error");
// 2) 显示对话框 — 用户按 OK / Cancel 之前阻塞
if( GUI.ShowDialog(/*viewModuleName*/"ModifyDlg") == false )
{
Log($"DB_OpenModifyDlg : cancelled by user");
return false;
}
// 3) OK 时用编辑结果 UPDATE
return DB_UpdateModified();
}三步分得很清楚:
- DB → Edit 字段 拷贝(对话框显示之前)
GUI.ShowDialog—true(OK)/false(Cancel)- Edit 字段 → DB UPDATE(
DB_UpdateModified)
GUI.ShowDialog 的 OK / Cancel
对话框中的两个按钮各自带 DialogResult 属性。
| 按钮 | DialogResult | 效果 |
|---|---|---|
| OK | true | ShowDialog 返回 true 后关闭 |
| Cancel | false | ShowDialog 返回 false 后关闭 |
这一行约定让调用方代码非常简单。
3) 状态标签 — DbStatusText
Data.xms 中只有一行字符串变量:
string DbStatusText = "● CLOSED";把 ViewRun 右上角 XLabel 的 DataName 设为 Data::DbStatusText,只要在 DB_Open() 改为 "● OPEN"、在 DB_Close() 改为 "● CLOSED",画面就会自动跟随。
总结 — "只更新数据,画面就会跟上"
| 变量 | 控件属性 | 效果 |
|---|---|---|
DispData(array string) | XDataGrid.ItemsSourceDataName | DataGrid 行 |
SelectIndex(int) | XDataGrid.SelectIndexDataName | 选中行 0..N-1 / -1 |
Edit*(8 个) | 对话框控件 DataName | ModifyDlg 双向 |
DbStatusText(string) | XLabel.DataName | 状态文本 |
脚本只动变量即可 — 这就是 QMachineStudio 的数据优先 GUI 范式。下一章将用 事件(按钮点击) 把这套流程串起来。