📄 example_09_2.py
字号:
from Common import *
from Tkinter import *
from Example_09_1_data import *
from crilib import *
import sys, regex, serial, time, string, os
IGNORE = '\n\r'
class RS232(serial.Port):
def __init__(self):
serial.Port.__init__(self)
self.queryPat = regex.compile('^.*\?$')
def open(self, cfg):
self.debug = cfg['debug']
self._trace('RS232.open')
cfg['cmdsEchoed'] = FALSE
cfg['cmdTerm'] = '\r'
cfg['rspTerm'] = '\r'
cfg['rspType'] = serial.RSP_TERMINATED
serial.Port.open(self, cfg)
class MeterServer:
def __init__(self):
# Open up the serial port
try:
d = serial.PortDict()
d['port'] = serial.COM1
d['baud'] = serial.Baud1200
d['parity'] = serial.NoParity
d['dataBits'] = serial.WordLength7
d['stopBits'] = serial.TwoStopBits
d['timeOutMs'] = 1500
d['rspTerm'] = IGNORE
d['rtsSignal'] = 'C'
d['debug'] = FALSE
self.fd = RS232()
self.fd.open(d)
self.lfd = open('out.log', 'w')
except:
print 'Cannot open serial port (COM1)'
sys.exit()
def poll(self):
try:
line = self.fd.write('D\r')
# OK, read the serial line (wait maximum of 1500 mSec)
inl = self.fd.readTerminated()
self.lfd.write('%s\n' %inl)
return inl
except:
return 'XX Off '
class MultiMeter:
def __init__(self, master):
self.root = master
self.root.title("Digital Multimeter")
self.root.iconname('22-168a')
self.holdVal = '0.0'
self.curRange = None
self.lineOpen = FALSE
self.canvas = Canvas(self.root, width=300, height=694)
self.canvas.pack(side="top", fill=BOTH, expand='no')
self.img = PhotoImage(file='images/multimeter.gif')
self.canvas.create_image(0,0,anchor=NW, image=self.img)
self.buildScale()
self.root.update()
self.root.after(5, self.buildSymbols)
self.dataReady = FALSE
self.root.after(5, self.buildScanner)
self.multimeter = MeterServer()
self.root.after(500, self.doPoll)
def buildSymbols(self):
for x, y, font, txt, tag in PANEL_LABELS:
self.canvas.create_text(x, y, text=txt,
font=(font, 12),
fill="gray75",
anchor = CENTER,
tags=tag)
def buildScale(self):
self.canvas.create_line(75,150, 213,150,
width=1,fill="#333377")
self.Xincr = 140.0/40.0
self.X = x = 75
self.X1 = 213
y = 150
lbli = 0
for i in range(40):
lbl = ''
if i in [0,9,19,29,39]:
h = 6
lbl = `lbli`
lbli = lbli + 5
elif i in [5,14,24,34]:
h = 4
else:
h = 2
self.canvas.create_line(x,y, x,y-h,
width=1,fill="#333377")
if lbl:
self.canvas.create_text(x, y-5, text=lbl,
font=("Arial", 6),
fill="#333377",
anchor = S),
x = x + self.Xincr
def startAnimation(self):
self.animX = self.X
self.action = TRUE
self.root.after(30, self.animate)
def animate(self):
if self.action:
self.canvas.create_line(self.animX,155, self.animX,167,
width=2,fill="#333377",
tags='anim')
self.animX = self.animX + self.Xincr
if self.animX > self.X1:
self.animX= self.X
self.canvas.delete('anim')
self.root.after(30, self.animate)
else:
self.canvas.delete('anim')
def stopAnimation(self):
self.action = FALSE
def buildScanner(self):
self.primary_lookup = {}
for key, hasr, rfmt, un, sec in PRIMARY_DATA:
if not self.primary_lookup.has_key(key):
self.primary_lookup[key] = []
self.primary_lookup[key].append((hasr, rfmt, un, sec))
keys = SECONDARY_DATA.keys()
for key in keys:
img = SECONDARY_DATA[key][-2]
try:
if getattr(self, 'i%s' % key):
pass # Already done...
except:
setattr(self, 'i%s' % key,
PhotoImage(file="images/%s.gif" % img))
self.dataReady = TRUE
def doPoll(self):
if self.dataReady:
result = self.multimeter.poll()
if result:
self.updateDisplay(result)
self.root.after(1000, self.doPoll)
def getRange(self, tag, val, units):
matchlist = self.primary_lookup[tag]
if not matchlist: return None
gotIndex = None
gotOpenLine = FALSE
for hasr, rfmt, un, sec in matchlist:
if hasr and (string.find(val, 'L') >= 0):
if rfmt == string.strip(val):
gotIndex = sec
gotOpenLine = TRUE
else:
decimal = string.find(val, '.')
if decimal > 0:
if rfmt == `decimal`:
gotIndex = sec
else:
if not rfmt: # No decimals
gotIndex = sec
if gotIndex:
if not string.strip(units) == string.strip(un):
gotIndex = None
if gotIndex:
break
return (gotIndex, gotOpenLine)
def updateDisplay(self, result):
self.canvas.delete('display')
tag = result[:2]
val = result[3:9]
units = result [9:13]
# display the hold value
redraw = FALSE
try:
hold = string.atof(self.holdVal)
nval = string.atof(val)
if hold <= 0.0:
if nval < 0.0:
if nval < hold:
self.holdVal = val
redraw = TRUE
else:
hold = 0.0
if hold >= 0.0 and not redraw:
if nval >= 0.0:
if nval > hold:
self.holdVal = val
redraw = TRUE
else:
self.holdVal = '0.0'
redraw = TRUE
except ValueError:
self.holdVal = '0.0'
redraw = TRUE
if redraw:
self.canvas.delete('holdval')
self.canvas.create_text(263, 67, text=self.holdVal,
font=("Digiface", 16),
fill="#333377",
anchor = E,
tags="holdval")
range, openline = self.getRange(tag, val, units)
if range: # Change the control to reflect the range
if not self.curRange == range:
self.curRange = range
self.canvas.delete('control')
self.canvas.create_image(146, 441, anchor=CENTER,
image=getattr(self, 'i%s' % range), tags="control")
self.holdVal = '0.0' # reset
if openline:
self.startAnimation()
else:
self.stopAnimation()
# Now we will update the units symbols pn the display
ma,ua,a,mv,v,ko,mo,o,nf,uf,f,mhz,khz,hz,ac, ctrl, lbl = \
SECONDARY_DATA[range]
for tag in ['ma','ua','a','mv','v','ko','mo','o',
'nf','uf','f','mhz','khz','hz','ac']:
self.canvas.itemconfig(tag,
fill=['gray75','#333377'][eval(tag)])
# Update the label field if there is one
self.canvas.delete('label')
if lbl:
self.canvas.create_text(55, 150, text=lbl,
font=("Arial", 12),
fill="#333377",
anchor = CENTER,
tags="label")
# Finally, display the value
self.canvas.create_text(214, 100, text=val,
font=("Digiface", 48),
fill="#333377",
anchor = E,
tags="display")
######################################################################
if __name__ == '__main__':
root = Tk()
multimeter = MultiMeter(root)
multimeter.root.mainloop()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -