ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

WinCC画面图层显隐方案:从需求分析到脚本实现与验收

WinCC画面图层显隐方案:从需求分析到脚本实现与验收

简介:这份资源面向西门子WinCC的SCADA组态学习者与工业自动化工程师,聚焦画面图层隐藏与显示这一交互控制技巧,帮助解决复杂画面中对象分层管理、动态切换显示内容的实际问题,适合已具备WinCC基础、希望提升画面交互灵活性的中初级用户。压缩包共298个文件,约10.1MB,以rpl报表布局、pdl画面文件、sav与dum项目数据为主,另含xml、ini配置及mdf、ldf数据库文件,构成一套可直接打开参考的完整项目案例。资源围绕图层可见性控制展开,涉及VBS脚本编写、按钮点击等事件驱动逻辑,以及Layer.Visible属性的实际运用,读者可据此理解隐藏图层用于数据加载或错误提示的实现思路。目前已有2290人学习下载,可作为图层管理与脚本联动的实操范本,便于对照项目结构快速上手并迁移到自己的组态工程中。

1. 从一次画面卡顿说起:为什么图层显隐值得单独做一套方案

做 WinCC 项目的人大多有过这样的经历:画面越做越大,设备、管道、阀门、报警牌堆在同一张流程图上,运行起来切换一次就卡半秒,操作工还抱怨“想看的东西被别的元素压住了”。某高校自动化方向的课程设计里,一个学生把整条产线的设备全画在一个画面里,结果评审时导师只问了一句“如果只关心泵站,能不能把别的都收起来”,他当场愣住。这个需求本质上就是图层显隐——按工艺段、按权限、按运行状态控制画面元素的可见性。它看起来是个小功能,但真要做成可交付的方案,涉及画面结构规划、脚本触发、变量绑定和验收测试一整套东西。这篇方案面向正在做 WinCC 课程设计、毕设或现场交付的读者,把“画面图层隐藏显示”从一句需求拆成能照着搭的结构。

2. 需求与画面结构设计:先定图层划分,再谈脚本

2.1 图层显隐到底要解决哪几类场景

把需求摊开看,图层显隐通常落在三类场景上,方案设计前必须先确认自己属于哪一类,否则后面脚本会写得很别扭。

第一类是工艺段切换。一条产线分制浆、反应、灌装几段,操作工只关心当前工段,其他段的设备、管道、标注全部隐藏,画面立刻清爽。这类需求的特点是“互斥”——同一时刻只显示一个图层组,切换靠按钮或下拉框。

第二类是权限分层。操作员只能看基本流程,工程师能看到仪表参数和调试入口,管理员能看到诊断信息。这类需求是“叠加”关系,高权限图层覆盖在低权限之上,隐藏逻辑跟登录用户绑定。

第三类是状态驱动。设备故障时自动弹出报警图层,正常时收起;或者检修模式下显示检修标记图层。这类需求由变量触发,不需要人点按钮,脚本挂在变量变化事件上。

三类场景对画面结构的要求不同。互斥切换适合把每个工艺段做成独立图层组,叠加权限适合按“基础层—参数层—诊断层”纵向分层,状态驱动则要求触发图层放在最上层且默认隐藏。我一般会先画一张图层清单表,把每个图层的名称、归属场景、默认可见性、触发方式写清楚,再动手改画面。这张表后面直接变成验收清单,省得来回返工。

图层名称归属场景默认可见触发方式绑定变量
基础流程层全部是常显无
制浆段层工艺段切换否按钮互斥Tag_Segment
反应段层工艺段切换否按钮互斥Tag_Segment
参数层权限分层否登录等级Tag_UserLevel
诊断层权限分层否登录等级Tag_UserLevel
报警弹出层状态驱动否变量变化Tag_AlarmActive

这张表的价值在于:它逼你在写第一行脚本之前就想清楚“谁控制谁”。很多翻车案例都是图层建了一堆,触发关系没理清,最后按钮点下去两个图层同时亮,操作工一脸问号。

2.2 画面对象命名规范:给脚本留好抓手

WinCC 画面里的对象默认名字是“矩形1”“按钮3”,靠这种名字写脚本等于给自己挖坑。图层显隐的脚本要频繁引用对象,命名必须成体系。我的习惯是“图层前缀_对象类型_序号”,比如LYR_Reaction_Valve01、LYR_Param_Text07。前缀统一用LYR_开头,后面跟图层组缩写,这样在 VBS 里可以用通配或者按前缀遍历,批量设置可见性。

命名规范还要覆盖图层组本身。WinCC 的画面窗口对象支持嵌套,把同一工艺段的元素放进一个“画面窗口”或“组对象”,显隐时只操作这个容器,比逐个设置子对象属性快得多,也少出错。容器命名建议GRP_前缀加段名,例如GRP_Reaction。脚本里一行ScreenItems("GRP_Reaction").Visible = False就能收掉整段,维护时也一眼能看懂。

这里有个血泪经验:命名规范一定要在画面动工前定死,并且写进项目文档。中途改名的代价是脚本里所有引用全部失效,而且 WinCC 不会给你明显的报错,只是“点了没反应”,排查起来非常费时间。我见过一个课设小组,三个人各画各的,最后合并画面时命名冲突,光改名就耗掉两天。

2.3 图层容器选型:组对象、画面窗口还是独立画面

WinCC 里实现“一组元素一起显隐”有三种常见载体,选错了后面会很难受。

组对象最轻量,把若干元素框选后组合即可,显隐直接设Visible属性。适合元素不多、不需要独立脚本逻辑的图层。缺点是组内元素不能单独响应事件,且组对象在画面编辑器里层级调整不如独立对象灵活。

画面窗口适合内容多、需要复用的图层。把工艺段做成一个独立 PDL 文件,主画面里放一个画面窗口指向它,显隐控制画面窗口即可。好处是图层内容可以单独编辑、单独测试,主画面保持干净。缺点是画面窗口有额外的加载开销,数量多了切换会顿,而且画面窗口内的变量前缀要规划好,否则变量绑定会串。

独立画面切换严格说不算“图层显隐”,而是整页切换。它适合工艺段之间完全独立、没有共享元素的情况。如果主画面上有公共的标题栏、报警条需要常显,就不适合整页切,得回到前两种。

我的选型原则是:公共元素多、图层内元素少于三十个,用组对象;图层内容复杂且需要多人分工,用画面窗口;完全独立的工段页面,才考虑整页切换。课程设计规模一般用组对象加少量画面窗口就够,别一上来就堆画面窗口,加载慢的问题在低配机器上很明显。

3. 脚本实现:VBS 控制可见性的三种触发方式

3.1 按钮互斥切换:一个变量管住一组图层

工艺段切换最直接的实现是按钮加一个整型变量。变量Tag_Segment取值 1、2、3 分别代表三个工段,每个按钮的鼠标点击事件里给变量赋值,图层的可见性由变量变化事件统一处理。这样按钮只负责“发命令”,显隐逻辑集中在一处,改起来方便。

按钮脚本(VBS,挂在按钮的“鼠标单击”事件):

' 按钮:切换到反应段 ' Tag_Segment 为内部整型变量,1=制浆 2=反应 3=灌装 Dim objTag Set objTag = HMIRuntime.Tags("Tag_Segment") objTag.Write 2

这段只做一件事:把段号写进去。真正的显隐逻辑放在变量变化事件里,避免每个按钮重复写显隐代码。变量变化事件脚本:

' 挂在 Tag_Segment 的“变量变化”事件 ' 根据段号统一设置各图层容器可见性 Dim seg seg = HMIRuntime.Tags("Tag_Segment").Read ' 先全部隐藏,再按段号打开,避免残留 ScreenItems("GRP_Pulping").Visible = False ScreenItems("GRP_Reaction").Visible = False ScreenItems("GRP_Filling").Visible = False Select Case seg Case 1 ScreenItems("GRP_Pulping").Visible = True Case 2 ScreenItems("GRP_Reaction").Visible = True Case 3 ScreenItems("GRP_Filling").Visible = True End Select

先全隐藏再打开是刻意为之。如果只写“打开当前段”,上一次的图层不会自动收起来,点几次之后三个段全亮,画面又乱了。这个“先清零再赋值”的写法在状态类脚本里是通用习惯,代价几乎为零,能省掉大量“为什么两个图层同时显示”的排查。

参数说明:Tag_Segment建议建成内部变量,数据类型选“有符号 16 位”,不要用字符串,字符串比较在脚本里容易因为空格或大小写出问题。ScreenItems("GRP_xxx")里的名字必须和画面对象名完全一致,大小写敏感,改名前先全局搜索脚本引用。

3.2 权限分层:登录等级驱动叠加图层

权限图层的逻辑是“等级越高,可见的层越多”,属于叠加关系,不能像工艺段那样互斥。假设Tag_UserLevel取值 0=未登录 1=操作员 2=工程师 3=管理员,参数层在等级 2 以上可见,诊断层在等级 3 可见。

' 挂在 Tag_UserLevel 的“变量变化”事件 ' 叠加式显隐:低等级层始终可见,高等级层逐级打开 Dim lv lv = HMIRuntime.Tags("Tag_UserLevel").Read ' 参数层:工程师及以上 If lv >= 2 Then ScreenItems("GRP_Param").Visible = True Else ScreenItems("GRP_Param").Visible = False End If ' 诊断层:仅管理员 If lv >= 3 Then ScreenItems("GRP_Diag").Visible = True Else ScreenItems("GRP_Diag").Visible = False End If

这里没有“先全隐藏”,因为基础流程层是常显的,参数层和诊断层各自独立判断即可。注意判断用>=而不是=,这样以后加等级不用改脚本。权限变量通常由登录脚本写入,登录成功写等级,注销写 0,这部分和 WinCC 用户管理配合,方案里要把“谁在什么时候写这个变量”写清楚,否则验收时会出现“登录了但图层没变”的问题——多半是变量没写进去,而不是显隐脚本错了。

提示:权限图层不要用画面对象的“授权”属性硬扛全部逻辑。对象级授权在元素多的时候配置繁琐,且和脚本显隐混用容易出现“授权允许但脚本隐藏”的矛盾状态。统一用变量加脚本控制,授权属性只做最后一道保险。

3.3 状态驱动:报警图层自动弹出与收起

报警弹出层要求“有报警自动出现,报警消除自动收起”,触发源是报警状态变量。脚本挂在Tag_AlarmActive的变化事件上,同时要考虑画面切换后图层状态是否保持——这是状态驱动最容易翻车的地方。

' 挂在 Tag_AlarmActive 的“变量变化”事件 ' 报警激活时显示弹出层,并置顶 Dim act act = HMIRuntime.Tags("Tag_AlarmActive").Read If act = 1 Then ScreenItems("GRP_AlarmPopup").Visible = True ' 置顶,避免被其他图层遮挡 ScreenItems("GRP_AlarmPopup").ZOrder = 0 Else ScreenItems("GRP_AlarmPopup").Visible = False End If

ZOrder = 0是让弹出层排到最前,WinCC 里数值越小越靠前。如果不设,弹出层可能被后画的元素盖住,操作工看不到报警,这个坑在多层画面里很常见。另外,变量变化事件只在值“变化”时触发,如果画面打开时报警已经是激活状态,事件不会补触发,弹出层就不会显示。解决办法是在画面的“打开”事件里补一次状态同步:

' 挂在主画面的“打开”事件 ' 画面加载时同步一次报警图层状态,防止漏触发 If HMIRuntime.Tags("Tag_AlarmActive").Read = 1 Then ScreenItems("GRP_AlarmPopup").Visible = True ScreenItems("GRP_AlarmPopup").ZOrder = 0 Else ScreenItems("GRP_AlarmPopup").Visible = False End If

这段“打开时补同步”的代码看起来冗余,但它是状态驱动图层的后悔药。凡是依赖变量变化事件控制显隐的地方,都要问一句“画面刚打开时状态对不对”,答案往往是要补同步。工艺段和权限图层同理,画面打开事件里读一次当前变量值,把显隐刷一遍,能消掉一大类“切画面后图层错乱”的问题。

4. 避坑与排查:图层显隐最常见的五个翻车点

4.1 点了按钮没反应,脚本像没执行

现象:按钮点下去,变量值确实变了(用变量仿真或在线表格能看到),但图层纹丝不动。

原因:九成是变量变化事件没挂上,或者挂错了变量。WinCC 的变量变化事件挂在变量本身上,不是在画面里挂;如果变量是外部变量且通信质量差,变化事件可能不触发。另一种情况是脚本里对象名拼错,VBS 对不存在的对象不会抛明显错误,只是静默失败。

解决:先在变量管理里确认事件已挂载,再用HMIRuntime.Trace在脚本首行打日志,确认脚本是否进入。对象名用画面编辑器里复制全名的方式粘贴,不要手敲。外部变量触发不可靠时,改用画面周期事件轮询变量值做比较,牺牲一点实时性换稳定。

4.2 切画面回来图层全乱了

现象:在 A 画面切好图层,跳到 B 画面再回来,图层显示状态和离开时不一致,或者全部显示、全部隐藏。

原因:画面对象的Visible属性是运行时状态,画面关闭再打开会按设计时的默认值重建,脚本里的设置不会持久化。如果只在变量变化事件里设显隐,回来时没有触发源,状态就回到默认。

解决:每个画面的“打开”事件里补一次全量同步,按当前变量值把所有图层刷一遍。这是最稳的做法,代码量不大,但能根治。不要试图用全局脚本去“记住”状态,跨画面同步的复杂度远高于打开时重刷。

4.3 图层隐藏了但还能点到

现象:图层视觉上消失了,但点击原来按钮的位置仍然触发动作,或者 Tab 键还能切到隐藏元素。

原因:Visible = False只控制绘制,不控制交互。某些对象在隐藏状态下仍保留事件响应,尤其是 ActiveX 控件和部分智能对象。

解决:隐藏图层时同时设Enabled = False,恢复时再设回True。对于整组容器,容器禁用后子对象的交互一般也会被拦住。验收时要专门测“隐藏后点击原位置”,这是容易被漏掉的测试项。

4.4 图层多了切换明显卡顿

现象:图层数量上去以后,每次切换要等半秒到一秒,操作工连点几下画面就卡住。

原因:逐个设置大量对象的Visible属性会触发多次重绘;如果图层里还有趋势控件、ActiveX 这类重对象,每次显隐都重新初始化,开销很大。

解决:用容器(组对象或画面窗口)做显隐,把“多次属性写”压成“一次属性写”。重对象图层尽量用画面窗口按需加载,不用时把画面窗口的“显示”关掉而不是只隐藏内部元素。另外避免在变量变化事件里做循环遍历,能写死对象名就写死。

4.5 多人协作合并后脚本引用全断

现象:小组分工画画面,合并后图层显隐大面积失效,脚本里一堆对象找不到。

原因:各人本地命名不一致,或者合并时对象被重命名、层级被调整,脚本里的字符串引用对不上。

解决:动工前把命名规范和图层清单定死并共享,合并前先做一次命名核对。合并后用一个“自检脚本”遍历所有脚本引用的对象名,逐个确认存在。这个自检脚本不复杂,但能提前暴露问题,比运行时一个个点按钮排查高效得多。

5. 验收与答辩:用一张测试表把图层逻辑讲清楚

图层显隐这种功能,答辩时最怕被问“你怎么证明它是对的”。光说“我点了按钮它能变”不够,评审要看到覆盖各种边界的验证。我的做法是随方案附一张测试表,逐条跑、逐条记录,答辩时直接展示这张表,比口头描述有说服力。

编号测试项操作步骤预期结果实际结果
T01工艺段互斥依次点击三个段按钮每次仅对应段可见,其余隐藏
T02工艺段复位切到反应段后关闭再打开画面仍显示反应段
T03权限叠加依次以操作员、工程师、管理员登录参数层、诊断层按等级逐级出现
T04权限注销管理员注销参数层、诊断层全部隐藏
T05报警弹出触发报警变量弹出层出现且置顶
T06报警恢复报警消除弹出层收起
T07打开补同步报警激活状态下打开画面弹出层直接显示
T08隐藏不可点隐藏图层后点击原按钮位置无动作触发
T09切换性能连续切换十次无明显卡顿,状态正确

这张表里 T02、T07、T08 是最容易被忽略、也最容易被评审问到的三项。T02 考的是状态持久化,T07 考的是事件漏触发,T08 考的是可见性与交互分离。把这三项跑通,基本能说明方案考虑周全。

答辩陈述的顺序建议反过来讲:先展示测试表跑通的结果,再回头讲图层划分和脚本设计。评审先看到“能验证”,再听“怎么实现”,接受度会高很多。讲脚本时不要逐行念代码,挑“先全隐藏再打开”“打开时补同步”“隐藏同时禁用”这三个设计点讲,每个点说清楚“不这么做会出什么问题”,这比讲语法更能体现工程判断。

还有一个具体技巧:答辩现场如果条件允许,用变量仿真直接改Tag_Segment和Tag_UserLevel的值,让评审看到图层实时变化,比点按钮更直观,也顺便证明了脚本挂在变量事件上而不是按钮里。变量仿真在 WinCC 运行系统里就能开,提前把仿真面板配好,现场不慌。

从那以后我每次做带图层控制的画面,都会在动工前先把图层清单表和测试表一起写出来,两张表对着看,设计时就知道要测什么,验收时也不会漏项。这套习惯帮我省掉过好几次返工。希望帮到你。

本文还有配套的精品资源,点击获取

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进