Database 手册 · Chapter 7

画面绑定

示例画面分为两部分。

画面角色核心绑定
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 中,如下设置两个属性:

属性含义
ItemsSourceDataNameData::DispData数据网格显示的行数组
SelectIndexDataNameData::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
0idwidth 60
1order_nowidth 90
2menu_namewidth 120
3start_timewidth 160
4end_timewidth 160
5weight_gformat 0.0,width 80
6resultwidth 80
7is_errorwidth 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 / XCheckBoxDataName 属性设为这些变量名,用户输入便会自动回写到 Data::Edit*

对话框控件DataName建议只读
Id 显示Data::EditId
Order No 输入Data::EditOrderNo
Menu 输入Data::EditMenuName
Start timeData::EditStartTime
End timeData::EditEndTime
Weight (g)Data::EditWeightG
ResultData::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();
}

三步分得很清楚:

  1. DB → Edit 字段 拷贝(对话框显示之前)
  2. GUI.ShowDialogtrue(OK)/ false(Cancel)
  3. Edit 字段 → DB UPDATE(DB_UpdateModified)

GUI.ShowDialog 的 OK / Cancel

对话框中的两个按钮各自带 DialogResult 属性。

按钮DialogResult效果
OKtrueShowDialog 返回 true 后关闭
CancelfalseShowDialog 返回 false 后关闭

这一行约定让调用方代码非常简单。


3) 状态标签 — DbStatusText

Data.xms 中只有一行字符串变量:

string DbStatusText = "● CLOSED";

ViewRun 右上角 XLabelDataName 设为 Data::DbStatusText,只要在 DB_Open() 改为 "● OPEN"、在 DB_Close() 改为 "● CLOSED",画面就会自动跟随。


总结 — "只更新数据,画面就会跟上"

变量控件属性效果
DispData(array string)XDataGrid.ItemsSourceDataNameDataGrid 行
SelectIndex(int)XDataGrid.SelectIndexDataName选中行 0..N-1 / -1
Edit*(8 个)对话框控件 DataNameModifyDlg 双向
DbStatusText(string)XLabel.DataName状态文本

脚本只动变量即可 — 这就是 QMachineStudio 的数据优先 GUI 范式。下一章将用 事件(按钮点击) 把这套流程串起来。