Стрелочный виджет

Стрелочный измерительный виджет выводит на canvas измеренное значение аналогового сигнала.




def aMeterC – функция создания объекта
Возвратные значения:
return (c,'ameter',x,y,widgLen,widgHigh,maxValue,outerColor,nameValue)

с – ссылка на объект
‘ameter’ – строковый идентификатор объекта
х – координата х
у – координата у
widgLen – ширина виджета,
widgHigh – высота виджета,
maxValue – максимальное измеряемое значение,
outerColor – цвет заполнения ,
nameValue – название измеряемого значения

def aMeter – функция изменения значения
с – ссылка на объект canvas
nowValue – величина измеренного значения
х – координата х
у – координата у
widgLen – ширина виджета,
widgHigh – высота виджета,
maxValue – максимальное измеряемое значение,
outerColor – цвет заполнения ,
nameValue – название измеряемого значения


def aMeterC(nowValue,x,y,widgLen,widgHigh,maxValue,outerColor,nameValue):
     c = Canvas(root,width=widgLen,height=widgHigh,bg="black",bd=0, highlightthickness=0, relief='ridge')
     c.place(x=x, y=y)
     if(nowValue > maxValue): nowValue=maxValue-1
     devValue=float(180) / float(maxValue)
     mesureValue = devValue * nowValue
     x1 = widgLen/2
     y1 = widgHigh/2 + 10
     x2 = 10
     y2 = widgHigh/2 + 10
     angle = math.pi * int(mesureValue) / 180;
     newx = ((x2-x1)*math.cos(angle)-(y2-y1)*math.sin(angle)) + x1
     newy = ((x2-x1)*math.sin(angle)+(y2-y1)*math.cos(angle)) + y1
     c.create_oval(1 , 1,widgLen-1 ,widgHigh-1,width=2,fill='black',outline=outerColor)
     c.create_text(7,y1,font="Verdana 10",anchor="w",justify=CENTER,fill=outerColor,text='0')
     c.create_text(widgLen-30,y1,font="Verdana 10",anchor="w",justify=CENTER,fill=outerColor,text=str(maxValue))
     c.create_text(widgLen/2-10,10,font="Verdana 10",anchor="w",justify=CENTER,fill=outerColor,text=str(maxValue/2))
     c.create_text(widgLen/8,widgHigh/4,font="Verdana 10",anchor="w",justify=CENTER,fill=outerColor,text=str(maxValue/4))
     c.create_text(widgLen/2+widgLen/4,widgHigh/4,font="Verdana 10",anchor="w",justify=CENTER,fill=outerColor,text=str(maxValue-maxValue/4))
     c.create_text(widgLen/2-20,widgHigh-40,font="Verdana 14",anchor="w",justify=CENTER,fill=outerColor,text=str(nowValue))
     c.create_rectangle(0,widgHigh/2+18,widgLen ,widgHigh,fill='black',outline='black')
     c.create_text(widgLen/2-20,widgHigh-40,font="Verdana 14",anchor="w",justify=CENTER,fill=outerColor,text=str(nowValue))
     c.create_text(6,widgHigh-20,font="Verdana 10",anchor="w",justify=CENTER,fill=outerColor,text=str(nameValue))
     c.create_oval(x1 - 10, y1 - 10, x1+ 10,y1 + 10,fill=outerColor,outline=outerColor)
     c.create_line(x1,y1,newx,newy,width=5,fill=outerColor)
     return (c,'ameter',x,y,widgLen,widgHigh,maxValue,outerColor,nameValue)

def aMeter(c,nowValue,x,y,widgLen,widgHigh,maxValue,outerColor,nameValue):
     if(nowValue > maxValue): nowValue=maxValue-1
     devValue=float(180) / float(maxValue)
     mesureValue = devValue * nowValue
     x1 = widgLen/2
     y1 = widgHigh/2 + 10
     x2 = 10
     y2 = widgHigh/2 + 10
     angle = math.pi * int(mesureValue) / 180;
     newx = ((x2-x1)*math.cos(angle)-(y2-y1)*math.sin(angle)) + x1
     newy = ((x2-x1)*math.sin(angle)+(y2-y1)*math.cos(angle)) + y1
     c.create_oval(1 , 1,widgLen-1 ,widgHigh-1,width=2,fill='black',outline=outerColor)
     c.create_text(7,y1,font="Verdana 10",anchor="w",justify=CENTER,fill=outerColor,text='0')
     c.create_text(widgLen-30,y1,font="Verdana 10",anchor="w",justify=CENTER,fill=outerColor,text=str(maxValue))
     c.create_text(widgLen/2-10,10,font="Verdana 10",anchor="w",justify=CENTER,fill=outerColor,text=str(maxValue/2))
     c.create_text(widgLen/8,widgHigh/4,font="Verdana 10",anchor="w",justify=CENTER,fill=outerColor,text=str(maxValue/4))
     c.create_text(widgLen/2+widgLen/4,widgHigh/4,font="Verdana 10",anchor="w",justify=CENTER,fill=outerColor,text=str(maxValue-maxValue/4))
     c.create_text(widgLen/2-20,widgHigh-40,font="Verdana 14",anchor="w",justify=CENTER,fill=outerColor,text=str(nowValue))
     c.create_rectangle(0,widgHigh/2+18,widgLen ,widgHigh,fill='black',outline='black')
     c.create_text(widgLen/2-20,widgHigh-40,font="Verdana 14",anchor="w",justify=CENTER,fill=outerColor,text=str(nowValue))
     c.create_text(6,widgHigh-20,font="Verdana 10",anchor="w",justify=CENTER,fill=outerColor,text=str(nameValue))
     c.create_oval(x1 - 10, y1 - 10, x1+ 10,y1 + 10,fill=outerColor,outline=outerColor)
     c.create_line(x1,y1,newx,newy,width=5,fill=outerColor)

Теперь вставим этот объект в программу

analogFig3=aMeterC(0,420,320,40,40,500,'green','analog Meter')
getAI=master.execute(1, cst.READ_INPUT_REGISTERS, 0, 10)
aMeter(analogFig2[0],getAI[1],420,320,40,40,500,'green','analog Meter')

Текст программы примет вид:

from Tkinter import *
import modbus_tk
import modbus_tk.defines as cst
import modbus_tk.modbus_tcp as modbus_tcp
import math
def aMeterC(nowValue,x,y,widgLen,widgHigh,maxValue,outerColor,nameValue):
     c = Canvas(root,width=widgLen,height=widgHigh,bg="black",bd=0, highlightthickness=0, relief='ridge')
     c.place(x=x, y=y)
     if(nowValue > maxValue): nowValue=maxValue-1
     devValue=float(180) / float(maxValue)
     mesureValue = devValue * nowValue
     x1 = widgLen/2
     y1 = widgHigh/2 + 10
     x2 = 10
     y2 = widgHigh/2 + 10
     angle = math.pi * int(mesureValue) / 180;
     newx = ((x2-x1)*math.cos(angle)-(y2-y1)*math.sin(angle)) + x1
     newy = ((x2-x1)*math.sin(angle)+(y2-y1)*math.cos(angle)) + y1
     c.create_oval(1 , 1,widgLen-1 ,widgHigh-1,width=2,fill='black',outline=outerColor)
     c.create_text(7,y1,font="Verdana 10",anchor="w",justify=CENTER,fill=outerColor,text='0')
     c.create_text(widgLen-30,y1,font="Verdana 10",anchor="w",justify=CENTER,fill=outerColor,text=str(maxValue))
     c.create_text(widgLen/2-10,10,font="Verdana 10",anchor="w",justify=CENTER,fill=outerColor,text=str(maxValue/2))
     c.create_text(widgLen/8,widgHigh/4,font="Verdana 10",anchor="w",justify=CENTER,fill=outerColor,text=str(maxValue/4))
     c.create_text(widgLen/2+widgLen/4,widgHigh/4,font="Verdana 10",anchor="w",justify=CENTER,fill=outerColor,text=str(maxValue-maxValue/4))
     c.create_text(widgLen/2-20,widgHigh-40,font="Verdana 14",anchor="w",justify=CENTER,fill=outerColor,text=str(nowValue))
     c.create_rectangle(0,widgHigh/2+18,widgLen ,widgHigh,fill='black',outline='black')
     c.create_text(widgLen/2-20,widgHigh-40,font="Verdana 14",anchor="w",justify=CENTER,fill=outerColor,text=str(nowValue))
     c.create_text(6,widgHigh-20,font="Verdana 10",anchor="w",justify=CENTER,fill=outerColor,text=str(nameValue))
     c.create_oval(x1 - 10, y1 - 10, x1+ 10,y1 + 10,fill=outerColor,outline=outerColor)
     c.create_line(x1,y1,newx,newy,width=5,fill=outerColor)
     return (c,'ameter',x,y,widgLen,widgHigh,maxValue,outerColor,nameValue)

def aMeter(c,nowValue,x,y,widgLen,widgHigh,maxValue,outerColor,nameValue):
     if(nowValue > maxValue): nowValue=maxValue-1
     devValue=float(180) / float(maxValue)
     mesureValue = devValue * nowValue
     x1 = widgLen/2
     y1 = widgHigh/2 + 10
     x2 = 10
     y2 = widgHigh/2 + 10
     angle = math.pi * int(mesureValue) / 180;
     newx = ((x2-x1)*math.cos(angle)-(y2-y1)*math.sin(angle)) + x1
     newy = ((x2-x1)*math.sin(angle)+(y2-y1)*math.cos(angle)) + y1
     c.create_oval(1 , 1,widgLen-1 ,widgHigh-1,width=2,fill='black',outline=outerColor)
     c.create_text(7,y1,font="Verdana 10",anchor="w",justify=CENTER,fill=outerColor,text='0')
     c.create_text(widgLen-30,y1,font="Verdana 10",anchor="w",justify=CENTER,fill=outerColor,text=str(maxValue))
     c.create_text(widgLen/2-10,10,font="Verdana 10",anchor="w",justify=CENTER,fill=outerColor,text=str(maxValue/2))
     c.create_text(widgLen/8,widgHigh/4,font="Verdana 10",anchor="w",justify=CENTER,fill=outerColor,text=str(maxValue/4))
     c.create_text(widgLen/2+widgLen/4,widgHigh/4,font="Verdana 10",anchor="w",justify=CENTER,fill=outerColor,text=str(maxValue-maxValue/4))
     c.create_text(widgLen/2-20,widgHigh-40,font="Verdana 14",anchor="w",justify=CENTER,fill=outerColor,text=str(nowValue))
     c.create_rectangle(0,widgHigh/2+18,widgLen ,widgHigh,fill='black',outline='black')
     c.create_text(widgLen/2-20,widgHigh-40,font="Verdana 14",anchor="w",justify=CENTER,fill=outerColor,text=str(nowValue))
     c.create_text(6,widgHigh-20,font="Verdana 10",anchor="w",justify=CENTER,fill=outerColor,text=str(nameValue))
     c.create_oval(x1 - 10, y1 - 10, x1+ 10,y1 + 10,fill=outerColor,outline=outerColor)
     c.create_line(x1,y1,newx,newy,width=5,fill=outerColor)
master = modbus_tcp.TcpMaster(host='192.168.0.1', port=502)
master.set_timeout(1.0)

root = Tk()
im = PhotoImage(file='bg.gif')
canv = Canvas(root,width=1900,height=950,bg="black",bd=0, highlightthickness=0, relief='ridge')
canv.place(x=0, y=25)
canv.create_image(1, 1,anchor=NW, image=im)
nText=canv.create_text(10,10,text="000",font="Verdana 12",anchor="w",justify=CENTER,fill='white')

analogFig3=aMeterC(0,420,320,140,140,1000,'green','analog Meter')

getAI=master.execute(1, cst.READ_INPUT_REGISTERS, 0, 10)
getDI=master.execute(1, cst.READ_DISCRETE_INPUTS, 0, 10)

canv.itemconfig(nText,text=str(getDI[0]))


analogFig3[0].delete("all")
aMeter(analogFig3[0],getAI[2],420,320,140,140,500,'green','analog Meter')
root.mainloop()

В координатах х=420, у=320 будет отображаться стрелочный измерительный прибор со значением регистра [2].