我的第一个控件设计
前两天,有一个客户需要做一个测量仪器,是一个传感器矩阵,测量众多数据的平衡特性,给我们提的需求如下:
- 1.能够插入一个矩阵图(如果不好实现,也可以通过手动一块一块的添加每一个小方块,最后拼成大方块)
- 2.每个小方块具有多种显示状态,每种状态对应的文字及颜色依据可由用户设定,比如:0对应绿色背景色,"合格",1对应黄色背景色,"偏低",2对应红色背景色,"偏高"
- 3.屏幕通过串口收到每个小方格的状态数据后,依据接收的数据显示文字和颜色,比如收到的状态为1,则对应小方块背景色黄色,并在中间显示"偏低"
- 如图:
分析
接到需求后我们进行了如下分析:
- 屏幕支持从串口使用数据绑定传入字符串变量,因此6X9的格子来说,我们可以传入一个54字节长度的字符串来描述每个格子的状态,字符串示例:1202021111111012.......
- 考虑到其他用户做类似需求使用的方便程度,我们决定将此功能封装成一个控件,因此我们需要分析一下这个控件可变的参数,也就是我们说的控件属性:
- 1、格子的数量可单独设置,也就是说6X9可由用户指定,比如改成5X4
- 2、每个格子的大小可以指定
- 3、表格的边框线的颜色可以指定
- 4、单元格的背景色对应0、1、2三种情况可以指定颜色
- 5、单元格中显示汉字的点阵大小和颜色可以指定
于是,我们得到了以下属性设置:
str text="1111111000000011111110000000111111100000001111111";
#defattr(text,str,"测量结果字符串,每字节对应一个格子,0-正常 1偏低 2偏高");
int dotm = 16;
#defattr(dotm,select,"显示汉字的点阵大小","16:16点阵;24:24点阵;32:32点阵;48:48点阵;64:64点阵");
int cc = 15;#defattr(cc,color,"显示汉字的颜色");
int c0 = 2;#defattr(cc,color,"偏低的单元格背景颜色");
int c1 = 1;#defattr(cc,color,"偏高的单元格背景颜色");
int bc = 63;#defattr(bc,color,"正常数据的背景颜色");
int tc=15;#defattr(tc,color,"表格框颜色");
int xn=7;#defattr(xn,int,"横向格子的数量");
int yn=7;#defattr(yn,int,"纵向格子的数量");
int tw=40;#defattr(tw,int,"单元格子的宽度");
int th=20;#defattr(th,int,"单元格子的高度");
控件制作操作
- 菜单:控件--->创建一个新控件
由于tablestatus在控件中已经存在,因此这次我们以tablestatus_demo为名称来写说明,点击确定后:
此时点击“保存并编译控件”,该控件就会出现在控件列表中:
找一个空页面,就可以放置该控件了,为了方便,我们把演示系统的第一个界面清空
点击“刷新效果”后,界面就出来了,由于控件没有任何代码,因此是空的
- 贴入属性代码
str text="1111111000000011111110000000111111100000001111111";
#defattr(text,str,"测量结果字符串,每字节对应一个格子,0-正常 1偏低 2偏高");
int dotm = 16;
#defattr(dotm,select,"显示汉字的点阵大小","16:16点阵;24:24点阵;32:32点阵;48:48点阵;64:64点阵");
int cc = 15;#defattr(cc,color,"显示汉字的颜色");
int c0 = 2;#defattr(cc,color,"偏低的单元格背景颜色");
int c1 = 1;#defattr(cc,color,"偏高的单元格背景颜色");
int bc = 63;#defattr(bc,color,"正常数据的背景颜色");
int tc=15;#defattr(tc,color,"表格框颜色");
int xn=7;#defattr(xn,int,"横向格子的数量");
int yn=7;#defattr(yn,int,"纵向格子的数量");
int tw=40;#defattr(tw,int,"单元格子的宽度");
int th=20;#defattr(th,int,"单元格子的高度");
其中宏语句#defattr参见 defattr
- 设计 create方法:
create的意思是“创建”,因此控件在一开始创建的时候就会执行这个函数,我们需要在这里重新计算一下控件的长宽,于是,create方法改成:
//---create():控件的初始化,可以在此书写有关默认参数的初始化
void create()
{ //在此书写当前页的初始化,比如根据图片的大小,重新计算x2,y2
x2=x1+tw*xn;
y2=y1+yn*th;
}
此时,可以看一下效果,点击“保存和编译控件”,然后再点击刷新效果,可以看到控件大小已经重新修正过了,而另一侧的控件属性也按照预设显示出来了;
- 设计draw方法,绘制背景
//---draw():绘制背景,所有不变的东西,不随数据变化的东西都称之为背景界面
void draw()
{ //在此书写绘制背景的语句
//automode(bc); or tranmode(n);//选择显示模式,具体讲解请参见语句说明书
int i;
automode(bc);
//画横线
for (i=0;i<=yn;i++){
pl(x1,y1+i*th,x2,y1+i*th,tc);
}
//画竖线
for (i=0;i<=xn;i++){
pl(x1+i*tw,y1,x1+i*tw,y2,tc);
}
}
绘制背景,实际上就是画一堆横线和竖线组成表格;同样,编译和刷新后:
表格背景已经绘制出来了
- 设计show方法,绘制前景,也就是刷新数据
//---show():刷新前景数据,也就是自定义属性发生变化时,界面跟着变得部分
void show()
{ //在此书写刷新前景的语句
//automode(bc); or tranmode(n); //选择显示模式,具体讲解请参见语句说明书
int i;
int j;
str s;
int jbc;
int sname;
if (strlen(text)<xn*yn) return;
automode(bc);
for (j=0;j<yn;j++){
for(i=0;i<xn;i++){
s=substr(text,j*xn+i,1);
if (s=="0"){
sname="正常";
jbc=bc;
}else{
if (s=="1"){
sname="偏低";
jbc=c0;
}else{
if (s=="2"){
sname="偏高";
jbc=c1;
}
}
}
label(dotm,x1+i*tw+1,y1+j*th+1,x1+i*tw+tw-1,y1+j*th+th-1,sname,cc,jbc,1);
}
}
}
首先,我们要判定一下,text字符串的长度一定要大于格子数量,否则不符合规则;然后横竖循环表格,根据字符串的字符来控制单元格的背景色和显示文字,代码比较简单,可自行阅读
同样,编译和刷新后:
控件显示正常
- 测试:修改 text 内容后:点击刷新:
调整颜色,测试,并同一界面放置2个控件: