TkLCD

Stellt hier eure Projekte vor.
Internetseiten, Skripte, und alles andere bzgl. Python.
Antworten
mawe
Python-Forum Veteran
Beiträge: 1209
Registriert: Montag 29. September 2003, 17:18
Wohnort: Purkersdorf (bei Wien [Austria])

Donnerstag 23. Dezember 2004, 08:12

Hi!

Genau wie wuf hab ich gestern versucht, ein LCD-ähnliches Ding für Tkinter zu programmieren (Zufälle gibts :wink:). Mein Ansatz ist etwas anders, und ich hab gleich ein Tkinter-Widget daraus gemacht. Hier mal die erste pre-pre-Alpha Version:

Code: Alles auswählen

from Tkinter import *

class TkLCD(Canvas):
	def __init__(self,master,width=100,height=50,colors=("cyan","blue"),
				digits=0,mask=0,**kw):
		Canvas.__init__(self,master,kw,width=width,height=height)
		 
		#    -      b
		#   | |    a c
		#    -      g
		#   | |    f d
		#    -      e
		# polygon coordinates for height=50	
		self.shape = {
    		'a' : [3.0,   5.0,  5.0,  3.0,  7.0,  5.0,  7.0, 15.0,  5.0, 17.0,  3.0, 15.0],
	    	'b' : [6.3,   2.0,  8.5,  0.0, 18.5,  0.0, 20.3,  2.0, 18.1,  4.0,  8.1,  4.0],
    		'c' : [19.0,  5.0, 21.2,  3.0, 23.0,  5.0, 23.0, 15.0, 21.2, 17.0, 19.0, 15.0],
		    'd' : [19.0, 21.0, 21.2, 19.0, 23.0, 21.0, 23.0, 31.0, 21.2, 33.0, 19.0, 31.0],
		    'e' : [6.3,  34.0,  8.5, 32.0, 18.5, 32.0, 20.3, 34.0, 18.1, 36.0,  8.1, 36.0],
		    'f' : [3.0,  21.0,  5.0, 19.0,  7.0, 21.0,  7.0, 31.0,  5.0, 33.0,  3.0, 31.0],
		    'g' : [6.3,  18.0,  8.5, 16.0, 18.5, 16.0, 20.3, 18.0, 18.1, 20.0,  8.1, 20.0],
		}

		factor = 50.0 / height
	
		# scale the shape	
		for c in self.shape.keys():
			self.shape[c] = [x/factor for x in self.shape[c]]
		
		# scale x and y offset
		self.delta_x = 24 / factor
		self.delta_y = 10 / factor
		
		# we will need those later	
		self.digits = digits
		self.colors = colors
		self.mask  = mask

		# llcd defines a list of segments to turn on for any particular symbol.
		self.llcd = {
			'0' : ["a","b","c","d","e","f"],
			'1' : ["c","d"],
			'2' : ["b","c","e","f","g"],
			'3' : ["b","c","d","e","g"],
		    '4' : ["a","c","d","g"],
		    '5' : ["a","b","d","e","g"],
		    '6' : ["a","b","d","e","f","g"],
		    '7' : ["b","c","d"],
		    '8' : ["a","b","c","d","e","f","g"],
		    '9' : ["a","b","c","d","e","g"],
		    '-' : ["g"],
		    ' ' : ''
		}
	
	def clear_lcd(self):
		self.delete('lcd')

	def change_colors(self, new):
		self.colors = new

	def reset_colors(self):
		self.colors = ("cyan","blue")

	def display(self, n):
		self.update()
		self.clear_lcd()
		number = [x for x in str(n)][::-1]
		if self.mask == 1:
			self.__create("8"*self.digits,1)
		self.__create(number)
		
	def __create(self,number,mask=None):
		if mask:
			out,fill = "white","grey"
		else:
			out,fill = self.colors
		w = self.winfo_width()
		b = int(self.cget('bd'))
		offset = w - self.delta_x - b - 5
		for char in number:
			for sign in self.llcd[char]:
				new = self.shape[sign][:]
				for i in range(len(new)):
					# x + offset
					if i%2==0: new[i] += offset
					# y + offset
					else: new[i] += self.delta_y+b
				self.create_polygon(new,outline=out,fill=fill,tags='lcd')
			offset -= self.delta_x


if __name__ == '__main__':
	
	def show_it(event):
		number = scale.get()
		if number > 0: 
			lcd2.change_colors(("blue","red"))
			lcd3.change_colors(("blue","red"))
		else: 
			lcd2.reset_colors()
			lcd3.reset_colors()
		lcd2.display(number)
		lcd3.display(number)
	
	root = Tk()
	
	lcd1 = TkLCD(root,width=350,height=60,mask=1,digits=11)
	lcd1.pack(anchor=E)
	lcd1.display(-1234567890)
	
	f = Frame(root,bd=2,relief=GROOVE)
	f.pack()

	lcd2 = TkLCD(f,height=100)
	lcd2.pack(side=LEFT)
	
	scale = Scale(f,orient=HORIZONTAL,from_=-100,to=100,
					showvalue=0,length=200,command=show_it)
	scale.pack(side=LEFT)

	lcd3 = TkLCD(f,digits=4,mask=1)
	lcd3.pack(side=RIGHT)

	root.mainloop()
Zum Schluß noch eine Frage: Statt mit change_colors hätte ich gerne, daß man die Farben mit dem Tkinter-üblichen configure verändern kann. Wie macht man das?

Gruß, mawe
Benutzeravatar
wuf
User
Beiträge: 1477
Registriert: Sonntag 8. Juni 2003, 09:50

Freitag 24. Dezember 2004, 00:49

Hallo mawe

Wenn Du beim Erstellen des Polygon-Objektes dessen Objektnummer
sicherst (eventuell in einer Liste) hast Du nachher über diese
Objektnummer (tag) Zugriff auf das Polygon-Objekt mit der Methode:

canvaswidget.itemconfigure(Objektnummer,Options)

z.B.

Erstellen des Polygon-Objektes mit:

objektnummer = canvaswidget.create_polygon(x0,y0,x1,y1.....)

Ändern der Polygon-Eigenschaften mit:

canvaswidget.itemconfigure(objektnummer,fill=mynewcolor)

N.B. Die Objektnummer ist eigendlich eine fortlaufende
Integer-Zahl, welche vergeben wird beim Ablegen eines
Canvas-Objektes auf die Canvasfläche.

Ich hoffe das geht in die Richtung was Du gemeint hast.

Gruss wuf :wink:
Take it easy Mates!
mawe
Python-Forum Veteran
Beiträge: 1209
Registriert: Montag 29. September 2003, 17:18
Wohnort: Purkersdorf (bei Wien [Austria])

Sonntag 26. Dezember 2004, 19:06

Hi wuf!

Vielen Dank für deinen Vorschlag, ist aber nicht ganz das was ich suche.
Ich möchte die colors genau so verändern können, wie z.B. die Hintergrundfarbe:

Code: Alles auswählen

lcd = TkLCD(root)
lcd.configure(bg="black")   # das geht
lcd.configure(colors=(None,"blue"))   # das will ich
bg ist ja irgendwie eine Eigenschaft vom Canvas, also müsste ich auch colors dazu machen. Hab keine Ahnung wie :?.
Naja, ich werd bei change_colors bleiben, ist auch für den Anwender etwas einleuchtender. Aber interessieren würd's mich schon ... :wink:

Gruß, mawe
Milan
User
Beiträge: 1078
Registriert: Mittwoch 16. Oktober 2002, 20:52

Sonntag 26. Dezember 2004, 19:36

Hi. Warum überschreibst du nicht einach die configure-Methode?

Code: Alles auswählen

    def configure(self,cnf={},**kw):
        colors=cnf.pop("colors",None) or kw.pop("colors",None)
        if colors:
            self.colors=colors
        return super(TKLCD,self).configure(cnf,**kw)
mawe
Python-Forum Veteran
Beiträge: 1209
Registriert: Montag 29. September 2003, 17:18
Wohnort: Purkersdorf (bei Wien [Austria])

Sonntag 26. Dezember 2004, 19:51

Hi Milan!

Geniale Idee! Steh allerdings auf der Leitung, weil ich eine Fehlermeldung bekomm:
Python hat geschrieben: TypeError: super() argument 1 must be type, not classobj
Gruß, mawe
Milan
User
Beiträge: 1078
Registriert: Mittwoch 16. Oktober 2002, 20:52

Sonntag 26. Dezember 2004, 19:56

Hi. Ist halt noch kein new-style ... Gut, dann auf die traditionelle Art und Weise :wink::

Code: Alles auswählen

    def configure(self,cnf={},**kw): 
        colors=cnf.pop("colors",None) or kw.pop("colors",None) 
        if colors: 
            self.colors=colors 
        return Canvas.configure(self,cnf,**kw)
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Sonntag 26. Dezember 2004, 19:58

Hi,

sind wohl noch oldstyleklassen bei TK?
Dann musst du die letzte Zeile so ändern:

Code: Alles auswählen

return Canvas.configure(self, cnf,**kw)

Gruß

Dookie
[code]#!/usr/bin/env python
import this[/code]
mawe
Python-Forum Veteran
Beiträge: 1209
Registriert: Montag 29. September 2003, 17:18
Wohnort: Purkersdorf (bei Wien [Austria])

Sonntag 26. Dezember 2004, 20:01

Hi!

@ Milan, Dookie:
Vielen Dank Euch beiden!
Gruß, mawe
Antworten