批量生成组态王画面

在一些大型工程中,点位特别多,几千甚至上万,这些点需要在画面中显示出来,但格式要求很简单,简单的指示灯,标签,输入输出框就可以.

这时,可以利用组态王的导入导出功能,将变量批量生成画面.

变量需提前整理好,放在excel里面,

 

读写列中 RWM 是指脉冲方式控制的数字量 在画面上按下置位,松开复位

RWD 是指电平方式控制的数字量 短按置位 长按复位

 

 然后,把需要生成画面的数据,复制到文本文件,运行python程序即可生成,可以导入组态王的生成画面的XML文件

复制代码
'''
用于生成组态王画面
弹窗式画面,包括指示灯,按钮(点击标签),数值显示,数值修改
'''
import datetime
def 标签长度计算(字符串):
    字符串长度 = len(字符串)
    汉字数量 = 0
    forin 字符串:
        if '\u4e00' <= 字 <= '\u9fff':
            汉字数量 += 1
    非汉字数量 = 字符串长度 - 汉字数量
    标签长度 = 汉字数量 * 20 + 非汉字数量 * 10
    return 标签长度



输入文件路径 = r"C:\Users\DP\Documents\姬超\工作\武夷新区恒冰冷链物流项目(1)\电气部分-3.1\画面 程序\上位机\py\输入文件测试.txt"
输入文件 = open(输入文件路径,'r',encoding = "utf-8")


# 读数据
数据列表 = []
for 行文本 in 输入文件:
    数据列表.append(行文本.replace('\n','').split('\t'))
输入文件.close()

# 定义输出文件各部件
# 起始编号,生成前需要修改
图形编号 = 6484
起始坐标 = [20,30]
行间隔 = 40
列间隔 = 300
指示灯与标签间隔 = 40
指示灯与数值显示间距 = 180
标签高度 = 30
# 标签宽度为每个字20 每个半角字10
画面名称 = "自动生成的画面" + datetime.datetime.now().strftime('%H%M%S')
文件头 = r'''<?xml version="1.0" encoding="UTF-16" standalone="yes"?>
<Picture>
    <Pic PictureGroupName="画面.弹窗" PicName="压缩机A" PicDocuVer="7.5" IsTitle="1" PictureType="2" IsChangeSize="1" FrameType="1" DocumentTop="84" DocumentLeft="481" DocumentBottom="1000" DocumentRight="1912" BackgroundCorlor="#04040400" PictureHeigth="1431" PictureWidth="916" PictureLeftTopX="0" PictureLeftTopY="0" Comment="" PriorityLevel="1" SecurityZoneID="1">
        <Element Number="6">
'''
文件尾 = r'''        </Element>
        <PicScript IntervalTime="3000">
            <Script Name="Show"><![CDATA[]]>
            </Script>
            <Script Name="While"><![CDATA[]]>
            </Script>
            <Script Name="Close"><![CDATA[]]>
            </Script>
        </PicScript>
    </Pic></Picture>
'''
指示灯模板 = r'''            <Ellipse Name="" Top="" Left="" Bottom="" Right="" AlignType="1" PenStyle="0" PenColor="#FFFFFF00" BrushStyle="0" BrushColor="#86868600" BrushHatch="0" BrushFillStyle="0" BrushFromCorlor="#86868600" BrushToCorlor="#00000000" IsLock="0" Comment="">
                <Link LinkType="FullFillProperty" Express="\\local\J事故风机1运行馈" Brush="{{192,192,192,0,0,0.000000},{0,255,0,0,0,1.000000}}"/>
            </Ellipse>
'''
普通标签模板 = r'''            <Label Name="" Top="" Left="" Bottom="" Right="" AlignType="1" PenStyle="0" PenColor="#00000000" BrushStyle="0" BrushColor="#FFFFFF00" BrushHatch="0" BrushFillStyle="0" BrushFromCorlor="#FFFFFF00" BrushToCorlor="#00000000" IsLock="0" Comment="" FontCorlor="#FFFFFF00" FontStyle="0" FontHeigth="30" FontWidth="10" FontIndex="0" FontHeight="-30" FontEscapement="0" FontOrientation="0" FontWeight="400" FontItalic="0" FontCharSet="0" FontOutPrecision1="3" FontClipPrecision="2" FontQuality="1" FontPitchAndFamily="2" FontName="宋体" TextCont="标签11" Director="0">
            </Label>
'''
不自复标签按钮模板 = r'''            <Label Name="" Top="" Left="" Bottom="" Right="" AlignType="1" PenStyle="0" PenColor="#00000000" BrushStyle="0" BrushColor="#FFFFFF00" BrushHatch="0" BrushFillStyle="0" BrushFromCorlor="#FFFFFF00" BrushToCorlor="#00000000" IsLock="0" Comment="" FontCorlor="#FFFFFF00" FontStyle="0" FontHeigth="30" FontWidth="10" FontIndex="0" FontHeight="-30" FontEscapement="0" FontOrientation="0" FontWeight="400" FontItalic="0" FontCharSet="0" FontOutPrecision1="3" FontClipPrecision="2" FontQuality="1" FontPitchAndFamily="2" FontName="宋体" TextCont="置位/长按复位" Director="0">
                <Link LinkType="CommandScript" Tip="" Key="无" Priority="0" Section="1">
                    <DownLink LinkType="DownLink"><![CDATA[\\local\J急停按钮馈=1;]]></DownLink>
                    <WhileLink LinkType="WhileLink"><![CDATA[\\local\J急停按钮馈=0;]]></WhileLink>
                    <UpLink LinkType="UpLink" Interval="800"><![CDATA[]]></UpLink>
                    <MoveInLink LinkType="MoveInLink"><![CDATA[]]></MoveInLink>
                    <MoveOutLink LinkType="MoveOutLink"><![CDATA[]]></MoveOutLink>
                </Link>
            </Label>
'''
自复标签按钮模板 = r'''            <Label Name="" Top="" Left="" Bottom="" Right="" AlignType="1" PenStyle="0" PenColor="#00000000" BrushStyle="0" BrushColor="#FFFFFF00" BrushHatch="0" BrushFillStyle="0" BrushFromCorlor="#FFFFFF00" BrushToCorlor="#00000000" IsLock="0" Comment="" FontCorlor="#FFFFFF00" FontStyle="0" FontHeigth="30" FontWidth="10" FontIndex="0" FontHeight="-30" FontEscapement="0" FontOrientation="0" FontWeight="400" FontItalic="0" FontCharSet="0" FontOutPrecision1="3" FontClipPrecision="2" FontQuality="1" FontPitchAndFamily="2" FontName="宋体" TextCont="按置松复" Director="0">
                <Link LinkType="CommandScript" Tip="" Key="无" Priority="0" Section="1">
                    <DownLink LinkType="DownLink"><![CDATA[\\local\J急停按钮馈=1;]]></DownLink>
                    <WhileLink LinkType="WhileLink"><![CDATA[]]></WhileLink>
                    <UpLink LinkType="UpLink" Interval="1000"><![CDATA[\\local\J急停按钮馈=0;]]></UpLink>
                    <MoveInLink LinkType="MoveInLink"><![CDATA[]]></MoveInLink>
                    <MoveOutLink LinkType="MoveOutLink"><![CDATA[]]></MoveOutLink>
                </Link>
            </Label>
'''
数值显示模板 = r'''            <Label Name="" Top="" Left="" Bottom="" Right="" AlignType="1" PenStyle="0" PenColor="#00000000" BrushStyle="0" BrushColor="#FFFFFF00" BrushHatch="0" BrushFillStyle="0" BrushFromCorlor="#FFFFFF00" BrushToCorlor="#00000000" IsLock="0" Comment="" FontCorlor="#00FF0000" FontStyle="0" FontHeigth="31" FontWidth="10" FontIndex="0" FontHeight="-31" FontEscapement="0" FontOrientation="0" FontWeight="400" FontItalic="0" FontCharSet="0" FontOutPrecision1="3" FontClipPrecision="2" FontQuality="1" FontPitchAndFamily="2" FontName="宋体" TextCont="000.0" Director="0">
                <Link LinkType="AnalogOutput" Express="\\local\TA泵投入数量" IntNum="4" DecimalNum="0" Binary="0"/>
            </Label>
'''
数值修改模板 = r'''            <Label Name="" Top="" Left="" Bottom="" Right="" AlignType="1" PenStyle="0" PenColor="#00000000" BrushStyle="0" BrushColor="#FFFFFF00" BrushHatch="0" BrushFillStyle="0" BrushFromCorlor="#FFFFFF00" BrushToCorlor="#00000000" IsLock="0" Comment="" FontCorlor="#00FF0000" FontStyle="0" FontHeigth="31" FontWidth="10" FontIndex="0" FontHeight="-31" FontEscapement="0" FontOrientation="0" FontWeight="400" FontItalic="0" FontCharSet="0" FontOutPrecision1="3" FontClipPrecision="2" FontQuality="1" FontPitchAndFamily="2" FontName="宋体" TextCont="000.0" Director="0">
                <Link LinkType="AnalogOutput" Express="\\local\TA泵投入数量" IntNum="4" DecimalNum="0" Binary="0"/>
                <Link LinkType="AnalogInput" Express="\\local\TA泵投入数量" Tip="请输入" Key="无" Priority="0" Section="1" MinValue="-1014" MaxValue="9898"/>
            </Label>
'''
元素数量统计 = 0
文件内容 = ''
临时文本 = ''
临时文本 = 文件头
元素数量 = len(数据列表) * 2
# 画面名称 和 元素数量 相关的更改
临时文本 = 临时文本.replace(r'Element Number="6"',r'Element Number="' + str(元素数量) + r'"')
临时文本 = 临时文本.replace(r'PicName="压缩机A"',r'PicName="' + 画面名称 + datetime.datetime.now().strftime('%H%M%S') + r'"')
文件内容 += 临时文本

'''数据列表的格式要求
    [0]->标签名
    [1]->变量名
    [2]->数据类型
    [3]->读写类型
'''
# 行数 和 列数 最终要替换为for循环
行数 = 1
列数 = 1
for 数据行 in 数据列表:
    if 数据行[2] == 'BOOL':
        '''生成指示灯'''
        # 编辑指示灯部分
        临时文本 = 指示灯模板
        # 定义图形名称
        图形编号 += 1
        临时文本 = 临时文本.replace(r'Name=""',r'Name="Graph' + str(图形编号) + r'"')
        # 定义指示灯位置
        临时文本 = 临时文本.replace(r'Top=""',r'Top="' + str(起始坐标[1] + (行数-1)*行间隔) + r'"')
        临时文本 = 临时文本.replace(r'Left=""',r'Left="' + str(起始坐标[0] + (列数-1)*列间隔) + r'"')
        临时文本 = 临时文本.replace(r'Bottom=""',r'Bottom="' + str(起始坐标[1] + (行数-1)*行间隔 + 30) + r'"')
        临时文本 = 临时文本.replace(r'Right=""',r'Right="' + str(起始坐标[0] + (列数-1)*列间隔 + 30) + r'"')
        # 替换指示灯变量
        临时文本 = 临时文本.replace(r'Express="\\local\J事故风机1运行馈"',r'Express="\\local' +chr(92) + 数据行[1] + r'"')
        # 如果是报警变量 则把指示灯改为红色
        if 数据行[1].count('') > 1 or 数据行[1].count('') > 1:
            临时文本 = 临时文本.replace(r'Brush="{{192,192,192,0,0,0.000000},{0,255,0,0,0,1.000000}}"',r'Brush="{{192,192,192,0,0,0.000000},{' + r'255,0,0' + r',0,0,1.000000}}"')
        文件内容 += 临时文本
        元素数量统计 += 1
    if ((数据行[2] == 'BOOL') and (数据行[3] == 'R')) or ((数据行[2] == 'INT') or (数据行[2] == 'LONG') or (数据行[2] == 'FLOAT')):
        '''生成标签'''
        # 编辑标签部分
        临时文本 = 普通标签模板
        # 定义图形名称
        图形编号 += 1
        临时文本 = 临时文本.replace(r'Name=""',r'Name="Graph' + str(图形编号) + r'"')
        # 定义标签位置
        临时文本 = 临时文本.replace(r'Top=""',r'Top="' + str(起始坐标[1] + (行数-1)*行间隔) + r'"')
        临时文本 = 临时文本.replace(r'Left=""',r'Left="' + str(起始坐标[0] + 指示灯与标签间隔 + (列数-1)*列间隔) + r'"')
        临时文本 = 临时文本.replace(r'Bottom=""',r'Bottom="' + str(起始坐标[1] + (行数-1)*行间隔 + 30) + r'"')
        临时文本 = 临时文本.replace(r'Right=""',r'Right="' + str(起始坐标[0] + 指示灯与标签间隔 + (列数-1)*列间隔 + 标签长度计算(数据行[0])) + r'"')
        # 定义标签文本
        临时文本 = 临时文本.replace(r'TextCont="标签11"',r'TextCont="' + 数据行[0] + r'"')
        文件内容 += 临时文本
        元素数量统计 += 1
    if (数据行[2] == 'BOOL') and (数据行[3] == 'RWD'):
        '''不自复,生成可点击标签,短按置位,长按复位'''
        # 编辑标签部分
        临时文本 = 不自复标签按钮模板
        # 定义图形名称
        图形编号 += 1
        临时文本 = 临时文本.replace(r'Name=""',r'Name="Graph' + str(图形编号) + r'"')
        # 定义标签位置
        临时文本 = 临时文本.replace(r'Top=""',r'Top="' + str(起始坐标[1] + (行数-1)*行间隔) + r'"')
        临时文本 = 临时文本.replace(r'Left=""',r'Left="' + str(起始坐标[0] + 指示灯与标签间隔 + (列数-1)*列间隔) + r'"')
        临时文本 = 临时文本.replace(r'Bottom=""',r'Bottom="' + str(起始坐标[1] + (行数-1)*行间隔 + 30) + r'"')
        临时文本 = 临时文本.replace(r'Right=""',r'Right="' + str(起始坐标[0] + 指示灯与标签间隔 + (列数-1)*列间隔 + 标签长度计算(数据行[0])) + r'"')
        # 定义标签文本
        临时文本 = 临时文本.replace(r'TextCont="置位/长按复位"',r'TextCont="' + 数据行[0] + r'"')
        # 替换变量
        临时文本 = 临时文本.replace(r'\\local\J急停按钮馈',r'\\local' +chr(92) + 数据行[1])
        文件内容 += 临时文本
        元素数量统计 += 1
    if (数据行[2] == 'BOOL') and (数据行[3]) == 'RWM':
        '''自复,生成可点击标签,按下置位,松开复位'''
        # 编辑标签部分
        临时文本 = 自复标签按钮模板
        # 定义图形名称
        图形编号 += 1
        临时文本 = 临时文本.replace(r'Name=""',r'Name="Graph' + str(图形编号) + r'"')
        # 定义标签位置
        临时文本 = 临时文本.replace(r'Top=""',r'Top="' + str(起始坐标[1] + (行数-1)*行间隔) + r'"')
        临时文本 = 临时文本.replace(r'Left=""',r'Left="' + str(起始坐标[0] + 指示灯与标签间隔 + (列数-1)*列间隔) + r'"')
        临时文本 = 临时文本.replace(r'Bottom=""',r'Bottom="' + str(起始坐标[1] + (行数-1)*行间隔 + 30) + r'"')
        临时文本 = 临时文本.replace(r'Right=""',r'Right="' + str(起始坐标[0] + 指示灯与标签间隔 + (列数-1)*列间隔 + 标签长度计算(数据行[0])) + r'"')
        # 定义标签文本
        临时文本 = 临时文本.replace(r'TextCont="按置松复"',r'TextCont="' + 数据行[0] + r'"')
        # 替换变量
        临时文本 = 临时文本.replace(r'\\local\J急停按钮馈',r'\\local' +chr(92) + 数据行[1])
        文件内容 += 临时文本
        元素数量统计 += 1
        
    if ((数据行[2] == 'INT') or (数据行[2] == 'LONG') or (数据行[2] == 'FLOAT')) and (数据行[3] == 'R'):
        '''生成数值显示'''
        # 编辑标签部分
        临时文本 = 数值显示模板
        # 定义图形名称
        图形编号 += 1
        临时文本 = 临时文本.replace(r'Name=""',r'Name="Graph' + str(图形编号) + r'"')
        # 定义标签位置
        临时文本 = 临时文本.replace(r'Top=""',r'Top="' + str(起始坐标[1] + (行数-1)*行间隔) + r'"')
        临时文本 = 临时文本.replace(r'Left=""',r'Left="' + str(起始坐标[0] + 指示灯与数值显示间距 + (列数-1)*列间隔) + r'"')
        临时文本 = 临时文本.replace(r'Bottom=""',r'Bottom="' + str(起始坐标[1] + (行数-1)*行间隔 + 30) + r'"')
        临时文本 = 临时文本.replace(r'Right=""',r'Right="' + str(起始坐标[0] + 指示灯与数值显示间距 + (列数-1)*列间隔 + 50) + r'"')
        # 替换变量
        临时文本 = 临时文本.replace(r'Express="\\local\TA泵投入数量',r'Express="\\local' +chr(92) + 数据行[1])
        文件内容 += 临时文本
        元素数量统计 += 1
    if ((数据行[2] == 'INT') or (数据行[2] == 'LONG') or (数据行[2] == 'FLOAT')) and (数据行[3] == 'RW'):
        '''生成数值编辑'''
        # 编辑标签部分
        临时文本 = 数值修改模板
        # 定义图形名称
        图形编号 += 1
        临时文本 = 临时文本.replace(r'Name=""',r'Name="Graph' + str(图形编号) + r'"')
        # 定义标签位置
        临时文本 = 临时文本.replace(r'Top=""',r'Top="' + str(起始坐标[1] + (行数-1)*行间隔) + r'"')
        临时文本 = 临时文本.replace(r'Left=""',r'Left="' + str(起始坐标[0] + 指示灯与数值显示间距 + (列数-1)*列间隔) + r'"')
        临时文本 = 临时文本.replace(r'Bottom=""',r'Bottom="' + str(起始坐标[1] + (行数-1)*行间隔 + 30) + r'"')
        临时文本 = 临时文本.replace(r'Right=""',r'Right="' + str(起始坐标[0] + 指示灯与数值显示间距 + (列数-1)*列间隔 + 50) + r'"')
        # 替换变量
        临时文本 = 临时文本.replace(r'Express="\\local\TA泵投入数量',r'Express="\\local' +chr(92) + 数据行[1])
        文件内容 += 临时文本
        元素数量统计 += 1
    行数 += 1
    if (起始坐标[1] + (行数-1)*行间隔) > 800:
        行数 = 1
        列数 += 1
    if 列数 > 3:
        行数 = 1
        列数 = 1
        print("画面可能已经画不下了,总共画了 " + str(元素数量统计) + " 个元素")
        break
文件内容 += 文件尾
输出文件路径 = r"C:\Users\DP\Documents\姬超\工作\武夷新区恒冰冷链物流项目(1)\电气部分-3.1\画面 程序\上位机\py\输出文件" + datetime.datetime.now().strftime('%H%M%S') + ".xml"
输出文件 = open(输出文件路径,'w',encoding = "utf-16")
输出文件.write(文件内容)

输出文件.close()
复制代码

 

posted @   急先锋小米  阅读(828)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示