程序页面里的三个页签,是怎样做出来的

阅读目录 · English

打开软件的“程序”页面,可以看到“刀路预览”“文件管理”“加工向导”三个页签。点击其中一个,下方就换成对应的内容。

这一篇就讲软件原来已有的这个功能。读完后,你应当能顺着页面找到脚本,并说清楚:点了哪里、哪个数发生变化、为什么显示这个页面、页面内容从哪个文件读进来。

不需要新增参数、按钮或页面,也不需要编译程序。下面的代码都是标准 env 中已有的写法。我们暂时只看三个子页面怎样切换,不展开文件管理操作和加工向导算法。

1.先在熟悉的界面中找到它

在主界面点击“程序”。它的下一行就是三个子页面的入口。先选择“刀路预览”:这个页签呈浅蓝色,下方左侧是刀路绘图区,右边是程序内容和 G/M 状态,再下面是加工文件列表。

标准程序页面,刀路预览已选中,左侧显示圆形铣底程序的刀路

点击截图可查看原图。

图 1 “程序 → 刀路预览”。示例文件为“圆形铣底.nc”:左侧从上方观察圆形刀路,右侧显示同一文件的程序内容,下方列出该文件。图中右侧第 10 行为蓝色选中行,左侧对应圆周呈红、紫相间的高亮。右上角红色状态标签显示“仿真”。本图只作离线预览,没有启动机床加工。

接着点击“文件管理”。这个页签变为浅蓝色,下方换成盘符和文件列表;右侧坐标、功能按钮以及底部功能键仍在原来的位置。

标准程序页面,文件管理已选中

点击截图可查看原图。

图 2 从“程序”进入,在下一行选择“文件管理”。图中的目录为示例,你的文件目录可以不同。

再点击同一行的“加工向导”。亮色移到了“加工向导”,下方出现“割方形框”“割圆形框”“铣矩形底”“铣圆形底”等内容。

标准程序页面,加工向导已选中

点击截图可查看原图。

图 3 点击“加工向导”后的页面。本篇只看页面怎样出现,不操作里面的“加载文件”或“执行”。图中的尺寸等数值是现有配置的显示值,不是本课要输入的加工参数。

观察这三张图时,只抓住两个变化:哪一个页签变亮,下面显示哪一块内容。 现有组态用同一个数,同时决定这两件事。

截图中的坐标和数值为示例,请以软件和机台的实际配置为准。

2.用一个数记住:现在看哪一页

在宏程序里,常用一个变量记录当前进行到哪一步。这里采用相似的办法,用 #810 记录当前选择的子页面。

#810 的值 当前选择 应当显示的内容
0 刀路预览 刀路预览区域
1 文件管理 文件管理页面
2 加工向导 加工向导页面

因此,点击“文件管理”时,首先发生的就是:

#810=1

点击“加工向导”时,则是:

#810=2

这两个赋值都已经写在原有页签的设置中,不需要操作者手工输入。#810 的这套 0/1/2 分工,是标准组态给这三个页面作出的约定。

另外还有一个容易看错的写法:#810.permission。在本例中,它记录的是上面一行选了哪个大页面,例如“程序”为 0;而 #810 记录的是程序下面选了哪个子页面。它们是同一参数的不同字段,不能混着使用。这里的 permission 字段被组态用作大页面选择,并不表示登录身份。

3.先找文件,再找页面上的名字

从软件运行目录进入 env。本篇主要看以下文件:

文件 本篇要看什么
env/dmec-app-black.ui 最外层主界面;其中装入标准主界面内容
env/maininterface/maininterface.ui “程序”入口、三个页签,以及各自内容的显示位置
env/file/filepage 点击“文件管理”时运行的脚本
env/file/file.ui 文件管理页面的具体布局
env/program/advancedpage 点击“加工向导”时运行的脚本
env/program/advanced.ui 加工向导页面的具体布局
env/main 启动时把选页值和首次打开标志准备好

.ui 文件描述页面上的控件、布局和设置;filepage、advancedpage 这样的无扩展名文件是组态脚本,可以用文本编辑器阅读。

如果用 Qt Designer 查看 maininterface.ui,在对象列表中找到下列名字。objectName 是控件在文件里的名字,方便脚本准确找到它;屏幕上显示的中文名称可以与它不同。

屏幕上的位置 文件里的名字(objectName)
“程序”入口 label_39
“刀路预览”页签 label_44
“文件管理”页签 label_45
“加工向导”页签 label_46
刀路预览的内容区域 frame_17
文件管理的内容区域 fileFrame
加工向导的内容区域 advancedFrame

这些页签在 UI 文件中使用的是标签控件 QLabel,组态给它们设置了点击动作,所以使用起来像按钮。下方三个内容区域使用 QFrame,可以把它理解为页面中预留的一块放内容的位置。

接下来主要看控件的 accessibleDescription 属性。这个英文名字是编辑器里的真实属性名;本系统把“显示什么、点击时做什么、什么时候显示”等组态写在这里。阅读 XML 文件时看到的 <、> 等属于 XML 转义;下面代码块按属性编辑器实际显示的文字书写。

4.点“文件管理”,为什么会运行那个脚本

找到 label_45,它的 accessibleDescription 原文是:

-T(#1100itemtitle6)
-A:(clickedEvent:/env/file/filepage[0](#810=1))
-C1(#810==1)
-C0(1)
-C(#929item5==1)
-V2
-D

先看第二行,不必一次记住所有写法:

-A:(clickedEvent:/env/file/filepage[0](#810=1))

它把三件事放在同一个设置里:

这一段 在本例中的意思
clickedEvent 点击这个页签时执行
(#810=1) 先把当前子页面记为文件管理
/env/file/filepage[0] 然后调用 env/file/filepage;[0] 选择调用脚本的通道

这里的 /env/... 按软件工作目录查找。[0] 不是“第 0 页”:本次选择的是文件管理,也就是 #810=1。先把赋值与文件路径看清,就能从界面一路找到要读的脚本。

其余几行分别负责文字、亮色和入口是否出现:

原有写法 做什么
-T(#1100itemtitle6) 从 #1100.itemtitle[6] 取得页签文字。中文语言包写入“文件管理”
-C1(#810==1) 当 #810 为 1 时,采用 1 号外观,即图中的选中亮色
-C0(1) 不满足前面的选中条件时,采用 0 号普通外观
-C(#929item5==1)、-V2 用第 3 个条件决定这个入口是否显示;文件管理功能开关为 1 时显示
-D 在运行中持续检查并更新这个控件,让文字和状态跟上参数变化

-V2 中的 2 是条件的编号,从 0 开始数:上面三条 -C… 依次为第 0、1、2 条。它也不是页码。条件式在前、显示设置引用哪一条在后,两者要一起读。

亮色本身不写在脚本中。三个页签共同所在的区域 frame_16 已经定义了 0 号和 1 号外观,页签只要说明“什么时候选哪一种”即可。

5.一个页签变亮,为什么下方内容也会换

在同一个 maininterface.ui 中找到 fileFrame。它的设置是:

-T(811)
-C(#810==1)
-V0
-D

这次先看后三行。这里只有一条条件,所以它的编号为 0:

-C(#810==1)
-V0
-D

意思是:检查 #810==1;条件成立就显示这个区域,不成立就隐藏;运行中继续更新。

另外两个内容区域分别检查 #810==0 和 #810==2。因此正常切换只要改一个 #810,就能让一块内容显示,另外两块隐藏。

点击后 页签为什么变亮 内容为什么出现
#810=0 刀路预览的 -C1(#810==0) 成立 frame_17 的显示条件成立
#810=1 文件管理的 -C1(#810==1) 成立 fileFrame 的显示条件成立
#810=2 加工向导的 -C1(#810==2) 成立 advancedFrame 的显示条件成立

页签和内容区域各有自己的设置,但都检查同一个选页值。 这就是两者能保持一致的原因。这里说的是更新后的对应关系,不承诺每个绘制动作在同一瞬间完成。

切走时,普通的显示/隐藏不会重新读取 UI 文件。那么,“文件管理”页面第一次是怎样放进 fileFrame 的?这要继续看点击时调用的脚本。

6.把 filepage 的七行读明白

env/file/filepage 的完整有效内容如下:

widgetFunc["disk","","",803]
IF#811.version==1GOTO1
#811.version=1
widgetFunc["dir",#802,"",802]
#811.itemdesc[0]="/env/file/file.ui"
widgetFunc["QFrame","fileFrame","refresh",""]
N1

如果你熟悉 IF/GOTO,先从第二行判断读起:以前准备过这个页面,就直接跳到 N1;否则完成一次准备。

第一次点进来

#811.version 在启动时已经被设为 0。所以第一次不会跳到 N1,会继续往下执行。

顺序 代码 本例中的作用
1 widgetFunc["disk","","",803] 把可用盘符的信息放入 #803,供左侧盘符列表使用
2 IF#811.version==1GOTO1 判断是否已经做过首次准备
3 #811.version=1 作一个“已经准备过”的标记
4 widgetFunc["dir",#802,"",802] 读取 #802 指定目录的内容,填入 #802 的文件列表数据
5 #811.itemdesc[0]="/env/file/file.ui" 记下这个区域要装入哪一个 UI 文件
6 widgetFunc["QFrame","fileFrame","refresh",""] 找到名为 fileFrame 的区域,按它的设置重新装入内容
7 N1 前面跳转所用的标号,随后文件结束

widgetFunc[...] 是组态调用已有界面功能的写法。这里只用到了列盘符、列目录和装入页面三个功能;不必先把它的全部命令学完。

文件名怎样传到页面上

把以下三处接起来看:

fileFrame 的设置:     -T(811)
脚本写入文件名:       #811.itemdesc[0]="/env/file/file.ui"
脚本要求装入:         widgetFunc["QFrame","fileFrame","refresh",""]

-T(811) 告诉这个区域“到 811 号参数里找内容说明”;该参数的 .itemdesc[0] 提供 UI 路径;refresh 才要求软件按这个说明装入页面。标准配置已经为 #811 准备了所需的子项。

注意,refresh 最后的 "" 是空字符串,文件路径写在前一行的 .itemdesc[0] 中。不要看到四个参数,就凭感觉把第四项当作 UI 文件名。

同样,不要把页签的 -T(#1100itemtitle6) 与区域的 -T(811) 混为一谈:前者给标签提供要显示的文字,后者给 QFrame 指定内容说明参数。要结合控件种类阅读。

切走以后,再点进来

此时 #811.version 已经是 1。脚本仍然先更新盘符,然后在第二行直接跳到 N1,不再重复执行目录首次读取、写 UI 路径和 refresh。

这也解释了为什么这个标志有用:页面切换负责让已有内容出现;首次准备负责把内容放进去。 每次切换都重新装入,会重新建立页面控件,不是现有组态的做法。

这里的 .version 是标准组态借用来保存标志的字段,不是软件版本号。现有脚本在装入 UI 之前就把它设成 1,所以这个值不能证明文件一定装入成功。如果文件丢失或名字写错,应继续查路径和文件,不能只看标志。

7.另外两页沿用了什么,哪里又不同

加工向导:用同样办法装入另一个 UI

“加工向导”的点击设置是:

-A:(clickedEvent:/env/program/advancedpage[0](#810=2))

它先选择第 2 页,再运行 advancedpage。这个脚本开头四行是:

IF#812.version==1GOTO1
#812.version=1
#812.itemdesc[0]="/env/program/advanced.ui"
widgetFunc["QFrame","advancedFrame","refresh",""]

这是原文件的开头节选,后面还有向导自身的准备工作以及 N1,不能把这四行当作完整替换文件。

与文件管理对照,就能看出共用的方法:

要决定什么 文件管理 加工向导
选择哪一页 #810=1 #810=2
放在哪个区域 fileFrame advancedFrame
到哪个参数找 UI 说明 -T(811) -T(812)
UI 文件名放哪里 #811.itemdesc[0] #812.itemdesc[0]
用什么记住已经准备过 #811.version #812.version

加工向导内部还用 #812 的数值选择向导类别。不要因为同样看到 812,就把它当成这里的三子页选择;本篇三页始终由 #810 决定。

刀路预览:内容已经放在主 UI 中

“刀路预览”的点击设置是:

-A:(clickedEvent:/env/null[1](#810=0))

env/null 是现有空脚本。这一项主要利用点击时的赋值,把 #810 改回 0。预览内容本来就在 maininterface.ui 中的 frame_17,所以不用像前两页那样,在首次点击时再读一个独立 UI 文件。

[1] 仍表示调用脚本的通道,并不表示选第 1 页。

8.开机时,为什么又回到刀路预览

在 env/main 中,可以找到这些原有赋值,下面按用途摘出:

#810.permission=0
#810=0

#811.version=0
#811.itemdesc[0]=""

#812.version=0
#812.itemdesc[0]=""

前两行选择“程序 → 刀路预览”。后面分别清掉文件页和向导页的首次准备标志、UI 文件路径。

这样,刚打开主界面时先显示预览;第一次点入文件管理或加工向导,才由它们自己的脚本填入路径并装入内容。只把页面隐藏起来,并不等于阻止软件在建立主界面时读取已经填好的 UI 路径,因此这里也会清空路径。

已经打开软件后,从“程序”切到别的大页面,再回到“程序”,情况不同:“程序”入口调用的 env/programpage 没有把 #810 清零。因此,在没有其他脚本改变选页值的情况下,可以保留之前选择的子页。切换语言、载入或恢复参数等流程另外有复位处理,不能把一次切页保留状态理解为永久记忆。

9.用一次操作,把设计过程串起来

现在回看“点击文件管理”这个动作,可以按下面的顺序讲给别人听:

  1. 在 maininterface.ui 中,label_45 是“文件管理”入口。
  2. 点击设置先执行 #810=1,随后运行 env/file/filepage。
  3. 因为 #810==1,这个页签使用亮色,fileFrame 被显示,另外两块内容被隐藏。
  4. 如果 #811.version 还不是 1,脚本写入 UI 路径,并让 fileFrame 装入 file.ui。
  5. 再次进入时,保留已经建立的页面,跳过首次准备部分。

设计这种页面时,现有组态实际解决了五个问题:用哪个数选页;点击时怎样改这个数;哪个区域显示;内容从哪个文件装入;什么时候需要重新准备。 这五件事合在一起,才是完整的三子页设计。

在软件副本中怎样核对

只切换页签即可,不需要运行加工程序,也不需要更改文件。

操作 观察什么
进入“程序”,点击“文件管理” “文件管理”变亮,出现盘符和文件列表
点击“加工向导” “加工向导”变亮,出现向导类别、尺寸输入和 MDI 区域
点击“刀路预览” 亮色和内容一起返回预览
再次点击“文件管理” 回到文件页;结合 IF/GOTO 理解这次为什么跳过首次准备

页面是否重新建立,不能仅凭肉眼判断。读者先通过上述操作核对显示效果,再对照脚本中的判断理解第一次与后续进入的区别。

遇到显示不对,先查哪儿

现象或容易产生的误解 对照哪里
找不到“文件管理”入口 看 label_45 的 #929.item[5] 条件;入口受这个现有功能开关控制
页签亮了,下方却不是对应内容 分别检查页签和内容区域是否都判断同一个 #810 值
文件页为空 查 fileFrame 的 -T(811)、#811.itemdesc[0]、UI 文件是否存在、refresh 中的名字是否为 fileFrame
看到 .version=1 就认为加载成功 这个值由脚本提前设置,不能替代对文件与实际页面的检查
把 [0]、-V2 当成页码 本例页码在 #810;另外两个数字分别属于脚本通道和条件编号
以为每次切页都要 refresh 普通切页使用显示条件;原设计只在需要建立内容时执行 refresh

现在,你可以把日常使用的三次点击,逐一对应到参数、页面设置和脚本。

下一课:文字、数值和状态 · 阅读目录