下拉框切换文字标签的数据来源 2026年11月2日
本例演示运行时选择“秒、分、时”,让同一个文字标签立即显示对应的系统变量。关键是:重新绑定后调用 refresh(),并把它放在实际发生切换的回调里。
| 下拉选项 | 选项值 ID | 标签绑定变量 |
|---|---|---|
| 秒 | 0 | $second |
| 分 | 1 | $minute |
| 时 | 2 | $hour |
以普通页面 Frm01 为例:文字标签名为 wMLabel1,下拉框名为 wMDropdown1,选择变量名为“变量_1”。其他工程使用自己的真实名称。
工程设置 → 实时变量:新建普通整型变量“变量_1”,初始值设为 0。只演示切换时,可不启用自动保存。
在页面放置文字标签 wMLabel1,初始绑定系统变量 $second。
放置下拉框 wMDropdown1,关联“变量_1”,按上表设置文字和选项值。
放置“变量消息”控件 wMVar1,关联“变量_1”,生成变量变化处理函数 onwMVar1Changed。函数名以实际生成结果为准。
打开页面的 C++ 文件,在 onLoad 和变量变化回调中加入下方代码。替换现有函数体,保留原有其他业务逻辑;不要重复粘贴函数定义。
bindData() 建立新变量的变化订阅,不能代替当前值的即时刷新。“分”或“时”短时间不变时,标签可能一直保留旧值。onLoad() 只处理页面进入;只在这里刷新,运行中的下拉切换仍然缺少刷新。
已有工程的最小修正:在变量变化回调中,所有绑定分支之后补上 wMLabel1->refresh();。
下面两个函数位于 Frm01.cpp。该写法把初始化与运行中切换统一交给变量变化回调,避免其中一条路径漏掉刷新。
void Frm01::onLoad() {
// 页面进入时也显示当前选择对应的值。
onwMVar1Changed(this, vm->get("变量_1"));
}
void Frm01::onwMVar1Changed(SttObject *org, IVariable *data) {
if (wMLabel1 == nullptr) return;
int index = 0;
if (!vm->getInt("变量_1", index)) return;
if (index < 0 || index > 2) return;
const char *names[] = {"$second", "$minute", "$hour"};
IVariable *target = vm->get(names[index]);
if (target == nullptr) return;
// 确认目标有效后,再解除旧绑定。
wMLabel1->disBindData();
wMLabel1->bindData(target);
// 立即显示当前值,不等待新变量下一次变化。
wMLabel1->refresh();
}
先检查选择值和目标变量,再解除旧绑定。这样选择值越界、变量读取失败或目标不存在时,不会主动清除原有绑定。
本例回调只负责显示,因此可以从 onLoad() 调用。如果原回调还有写设备或保存动作,应把公共的绑定与刷新代码抽成独立函数,避免打开页面时执行那些额外动作。
变量消息已经统一处理选择变化,下拉框自身的变化回调不必重复执行同一段代码。不要修改 IDE 自动生成的 createParts() 或控件声明。
bindData、disBindData 和 refresh 已在当前 SDK 中核对。前两个接口可能被代码助手隐藏,查询 SDK 时使用 STTWidget 的 --all 选项。
若要重启后记住选择,需对“变量_1”启用自动保存,在合适的确认动作中调用 vm->saveAll() 并检查返回值。保存的是 0、1、2;页面打开时由 onLoad() 恢复对应绑定。saveAll() 不负责刷新显示,也不会保存未启用自动保存的变量。
动态绑定只影响运行中的控件,不会反向修改 VMF 或属性面板的固定绑定。示例代码默认不保存;不要在每秒变化或循环中持续保存。
绑定普通变量或设备变量时,把 names 数组替换为真实变量名称,并核对数据类型。refresh() 显示当前缓存值,不等于立即读取 PLC;通信状态、轮询和驻留需求需单独核对。输入型控件还会涉及写入目标,应先在测试地址验证。
保存并编译,重新启动本次生成的模拟器。
在分钟未变化时选择“分”,应立即显示当前分钟;选择“时”应立即显示当前小时,无需重启。
切回“秒”,应立即显示秒值,并持续更新。重复往返切换,确认旧变量不再影响标签。
重新进入页面检查初始显示;有保存需求时,再单独验证重启后的选择是否保留。
| 现象 | 检查位置 |
|---|---|
| 切换后仍显示旧值 | 检查实际变量变化回调中是否调用 refresh();不能只放在 onLoad()。 |
| 完全不随选择变化 | 检查下拉框关联变量、选项值,以及变量消息是否触发。 |
| 修改后运行仍旧 | 确认已保存、编译成功,并运行了新产物。 |
| 重启后选择丢失 | 检查自动保存、saveAll() 返回值及页面恢复逻辑。 |
适用与验证:以 Java 版 ApusIDE 202611021406 和 testDynamicVar 工程为基础。原修复已通过 Debug 构建;本文整理后的代码通过当前 SDK 的语法检查。模拟器交互、真机运行与掉电保持需按上述步骤验证。