Seite 1 von 1

7-Segment Grossanzeige

Verfasst: Donnerstag 23. Dezember 2004, 00:25
von wuf
Hallo Tkinter Freunde

Habe mich einmal näher mit dem Canvas-Polygon
Grafikobjekt von Tkinter beschäftigt. Als Out-
put entstand dieser Prototyp. Eine skalierbare
7-Segment Grossanzeige.
Ein idealer Baustein für Uhrenmacher und Zähler-
bauer.

Slogan: Python & Tkinter are very good companions!

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

# Skriptname  : fwsSingle7SegDisplay0101.py
# Version     : 1.01
# Autor       : wuf @ german Python-Forum
# Datum       : 12.12.2004
# Geändert    : 12.12.2004
# Plattform   : OS       :SuSE91
#               Editor   :KWrite
#               Debugger :Bash-Shell
#               Sprache  :Python 2.3.3
#               GUI      :Tkinter  

from     Tkinter   import*
from     math      import*
from     copy      import*

class Digit:
	def __init__(self,xpos=0.0,ypos=0.0,factor=10.0,color='red',stipple=''):

		#~~ Buffer for Polypoints
		self.segmentobj    =  []
		self.points        =  None
		self.polypoints    =  []
		self.coordsegment  =  []
		self.coordpoints   =  {}
		self.segmentkeys   =  ('A','B','C','D','E','F','G')

		self.xp       = xpos
		self.yp       = ypos
		self.fill     = color
		self.stipple  = stipple
		self.outline  = platform['bg']
		self.gap      = 2
		self.factor   = factor
		self.curval   = None
	
		#~~ Koordinaten für die Segmentplatzierung
		#~~ Für Segment-A
		self.xpos    = self.xp + self.gap
		self.ypos    = self.yp
		self.coordsegment =  [[self.xpos,self.ypos]]

		#~~ Für Segment-B
		self.xpos    = self.xp + (self.factor * 10.0)-(self.factor * 2.0)+ self.gap*2
		self.ypos    = self.yp + self.gap
		self.coordsegment += [[self.xpos,self.ypos]]

		#~~ Für Segment-C
		self.xpos    = self.xp + (self.factor * 10.0)-(self.factor * 2.0)+self.gap*2
		self.ypos    = self.yp + (self.factor * 10.0)+(self.factor * 0.0) + self.gap*3
		self.coordsegment += [[self.xpos,self.ypos]]

		#~~ Für Segment-D
		self.xpos    = self.xp + self.gap
		self.ypos    = self.yp + (self.factor * 20.0)-(self.factor * 2.0) + self.gap*4
		self.coordsegment += [[self.xpos,self.ypos]]

		#~~ Für Segment-E
		self.xpos    = self.xp
		self.ypos    = self.yp + (self.factor * 10.0)+ self.gap*3
		self.coordsegment += [[self.xpos,self.ypos]]

		#~~ Für Segment-F
		self.xpos    = self.xp
		self.ypos    = self.yp + self.gap
		self.coordsegment += [[self.xpos,self.ypos]]

		#~~ Für Segment-G
		self.xpos    = self.xp + self.gap
		self.ypos    = self.yp + (self.factor * 10.0)-(self.factor * 1.0) + self.gap*2
		self.coordsegment += [[self.xpos,self.ypos]]

		#~~ Segment-Pattern für die Nummern 0-9
		self.segmentmask  =  [[1,1,1,1,1,1,0],  # 0
							  [0,1,1,0,0,0,0],  # 1
							  [1,1,0,1,1,0,1],  # 2
							  [1,1,1,1,0,0,1],  # 3
							  [0,1,1,0,0,1,1],  # 4
							  [1,0,1,1,0,1,1],  # 5
							  [1,0,1,1,1,1,1],  # 6
							  [1,1,1,0,0,0,0],  # 7
							  [1,1,1,1,1,1,1],  # 8
							  [1,1,1,1,0,1,1],  # 9
							 ]

		#~~ Koordinatenpunkte für die Segmente A-G
		self.coordpoints  =  {'A': [[0.0 ,0.0 ,1],  # Polygon-Eckpunkte Segment-A
									[10.0,0.0 ,2],
 									[8.0 ,2.0 ,3],
 									[2.0 ,2.0 ,3],
 									[0.0 ,0.0 ,1],
									],
							  'B': [[0.0 ,2.0 ,4],  # Polygon-Eckpunkte Segment-B
									[2.0 ,0.0 ,5],
 									[2.0 ,10.0,3],
 									[0.0 ,9.0 ,4],
 									[0.0 ,2.0 ,4],
									],
							  'C': [[0.0 ,1.0 ,4],  # Polygon-Eckpunkte Segment-C
									[2.0 ,0.0 ,5],
 									[2.0 ,10.0,3],
 									[0.0 ,8.0 ,4],
 									[0.0 ,2.0 ,4],
									],
							  'D': [[2.0 ,0.0 ,5],  # Polygon-Eckpunkte Segment-D
									[8.0 ,0.0 ,5],
 									[10.0,2.0 ,3],
 									[0.0 ,2.0 ,4],
 									[2.0 ,0.0 ,5],
									],
							  'E': [[0.0 ,0.0 ,1],  # Polygon-Eckpunkte Segment-E
									[0.0 ,10.0,4],
 									[2.0 ,8.0 ,3],
 									[2.0 ,1.0 ,3],
 									[0.0 ,0.0 ,1],
									],
							  'F': [[0.0 ,0.0 ,1],  # Polygon-Eckpunkte Segment-F
									[0.0 ,10.0,4],
 									[2.0 ,9.0 ,3],
 									[2.0 ,2.0 ,3],
 									[0.0 ,0.0 ,1],
									],
							  'G': [[0.0 ,1.0 ,4],  # Polygon-Eckpunkte Segment-G
									[2.0 ,0.0 ,2],
 									[8.0 ,0.0 ,2],
 									[10.0,1.0 ,3],
 									[8.0 ,2.0 ,3],
 									[2.0 ,2.0 ,3],
 									[0.0 ,1.0 ,4],
									]
							 }

		#~~ Platziere Segmente
		for segnum,segkey in enumerate(self.segmentkeys):
			self.xpos,self.ypos = self.coordsegment[segnum]
			self.points = deepcopy(self.coordpoints[segkey])
			self.DrawSegment(segkey)

		self.ShowNumber(0)

	def DrawSegment(self,segkey):
		self.polypoints = []
		for segment in self.coordpoints[segkey]:
			self.points = deepcopy(segment)
			for x,y,scale in [self.points]:
				if scale == 1:
					x += self.xpos
					y += self.ypos

				if scale == 2:
					x *= self.factor
					x += self.xpos
					y += self.ypos

				if scale == 3:
					x *= self.factor
					x += self.xpos
					y *= self.factor
					y += self.ypos

				if scale == 4:
					x += self.xpos
					y *= self.factor
					y += self.ypos

				if scale == 5:
					x *= self.factor
					x += self.xpos
					y += self.ypos

				#~~ Schreibt die modifizierten Punkte
				#   in die Segmentliste zurück
				self.points[0] = x
				self.points[1] = y

				#~~ Erzeugt Liste mit Poly-Koordinatenpunkte
				self.polypoints += [self.points[0:2]]

		self.segmentobj.append(platform.create_polygon(self.polypoints,
													   fill=self.fill,
													   outline=self.outline,
													   stipple=self.stipple
													   ))

	def ShowNumber(self,number):
		if self.curval == number:
			return
		self.curval = number
		mask = self.segmentmask[number]
		for segnum,segflag in enumerate(mask):
			if segflag:
				platform.itemconfigure(self.segmentobj[segnum],fill=self.fill,stipple=self.stipple)
			else:
				#platform.itemconfigure(self.segmentobj[segnum],fill=platform['bg'])
				platform.itemconfigure(self.segmentobj[segnum],fill=self.fill,stipple='gray12')
				
	def UpdateSegmentColor(self):
		mask = self.segmentmask[self.curval]
		for segnum,segflag in enumerate(mask):
			if segflag:
				platform.itemconfigure(self.segmentobj[segnum],fill=self.fill,stipple=self.stipple)
			else:
				#platform.itemconfigure(self.segmentobj[segnum],fill=platform['bg'])
				platform.itemconfigure(self.segmentobj[segnum],fill=self.fill,stipple='gray12')
				
class SegDisplay0101(Digit):

	def __init__(self,xpos=30.0,ypos=30.0,factor=10,color='red',stipple=''):
		#~~ Initialisierung
		Digit.__init__(self,xpos,ypos,factor,color,stipple)


#**********************************************
#* Test der 7-Segment-Anzeige
#**********************************************
def CountNumber():
	global counter
	#~~ Zählintervall
	strvalue = str(counter)
	maxnum = len(strvalue)
	digptr = 0
	
	for num in xrange(maxnum,0,-1):
		number = int(strvalue[num-1])
		digits[digptr].stipple = ''
		digits[digptr].ShowNumber(number)
		digptr += 1
		
	if counter < 9:
		counter += 1
	else:
		counter = 0

	platform.after(reptime,CountNumber)
	
def ChangeSegmentColor(event,obj):
	#~~ Ändert Segmentfarbe
 	digits[0].fill = fgcolor[obj]
 	digits[0].UpdateSegmentColor()
		
def ChangeBoxEnter(event):
	#~~ Ändert Kursor-Symbol von Pfeil in Hand um,
	#   wenn sich die Maus in die Farbauswahlbox
	#   bewegt.
	cursor = platform['cursor']
	platform['cursor'] = 'hand1'
	
def ChangeBoxLeave(event):
	#~~ Ändert Kursor-Symbol von Hand in Pfeil um,
	#   wenn sich die Maus aus der Farbauswahlbox
	#   bewegt.
	platform['cursor'] = root['cursor']

	
if __name__ == "__main__":
	root = Tk()
	
	root.title('7-Seg-Display')
	
	counter     = 0             # Zähler
	digits      = []            # Digit-Objektliste
	factor      = 20            # Segmentgrösse
	digitcolor  = 'steelblue3'  # Segmentfarbe
	reptime     = 500           # Zählintervall (ms)
	
	#~~ Symbol: Schraube im base64-Format
	#   GIF-Datei wurde mit Modul base64.py kodiert 
	#   Kommandozeile in Bash-Shell: python base64.py Schraube.gif
	#   Die Ausgabe der in das base64-Format kodierte Datei Schraube.gif er-
	#   folgt in die Bash-Shell. Dann manuell von der Bash-Shell in dieses Script
	#   unter variable data kopiert
	schraube=PhotoImage(
	data='R0lGODlhEQASAPcAAAAAAIuLi6ysrMDAwObm5v8A/wAAAAICAgICAgICAgICAgICAgICAgICAgIC'\
		 'AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC'\
		 'AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC'\
		 'AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC'\
		 'AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC'\
		 'AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC'\
		 'AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC'\
		 'AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC'\
		 'AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC'\
		 'AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC'\
		 'AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC'\
		 'AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC'\
		 'AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC'\
		 'AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgAAACH5BAkIAAUALAAAAAARABIA'\
		 'AAhqAAsIHEiwoMGDCAkCWLgwYYGFBCJGbGgQgMSLFgEUtBhxgMcBHAloHMjxI0iJFB92/BgSgMeR'\
		 'Fk22ZCkw5kuUHwXAZIkz586TE00K0ElypskAI2v2/BgA6UaRR5smVQigqdWUBxlidZgwIAA7')
	
	#~~ Anzeigerahmen
	clockframe = Frame(root,relief='raised',bd=8,bg='gray',highlightbackground='black',highlightthickness=1)
	clockframe.pack(fill=BOTH,expand=YES)
	
	#~~ Canvas für die Aufnahme des 7-Seg-Digit
	platform = Canvas(clockframe,
					  bg='black',
					  relief='ridge',
					  bd=8,
					  highlightthickness=0,
					  )
	platform.pack(padx=20,pady=40,fill=BOTH)
	
	platform['width']  = 285
	platform['height'] = 500
	root.update_idletasks()
	
	#~~ Zentriert das Root-Fenster
	width,height,left,top  = tuple(map(int,root.winfo_geometry().replace("x","+").split("+")))
	xpos   = (root.winfo_screenwidth()-width)/2
	ypos   = (root.winfo_screenheight()-height)/2
	root.wm_geometry("+%d+%d" % (xpos,ypos))
	root.update_idletasks()
	
	#~~ Platziert Schrauben
	width,height,left,top   = tuple(map(int,platform.winfo_geometry().replace("x","+").split("+")))
	platform.create_image(20,20, image=schraube)
	platform.create_image(20,height-20, image=schraube)
	platform.create_image(width-20,20, image=schraube)
	platform.create_image(width-20,height-20, image=schraube)
	platform.create_text(65,height-35,anchor=SW,text='Powered by Python & Tkinter',fill='white')
	
	#~~ Farbauswahlliste: Kann durch eigene Farben ergänzt oder
	#   erweitert verden.
	fgcolor = ['red','lightsalmon1','green','blue','steelblue3','yellow','white']
	xposptr = 0
	fgobj   = []
	
	#~~ Erzeuge Farbauswahl-Schaltflächen
	for box in xrange(len(fgcolor)):
		x1 = 40+xposptr
		y1 = height-25
		object = platform.create_rectangle(x1,y1,x1+10,y1+10,fill=fgcolor[box],stipple='gray50')
		platform.tag_bind(object,"<Button-1>",lambda e,obj=box:ChangeSegmentColor(e,obj))
		platform.tag_bind(object,"<Enter>"   ,ChangeBoxEnter)
		platform.tag_bind(object,"<Leave>"   ,ChangeBoxLeave)
		fgobj.append(object)
		xposptr += 15

	#~~ Erzeuge Digit-Objekt
	digits.append(SegDisplay0101(xpos     = 50,
								 ypos     = 40.0,
								 factor   = factor,
								 color    = digitcolor,
								 stipple  = ''
								 ))

	CountNumber()

	root = mainloop()
Gruss wuf :wink: