ich hab mich in den letzten Tagen. auch mal an einer 7-Segmentanzeige herangemacht. Herausgekommen ist ein Modul, das sich GUI-Unabhängig verwenden lässt.
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
Modul: SevenSegs
Description: GUI-indipend class for sevensegsdisplays
Version: 0.1
Copyright: 2004 by Fritz Cizmarov fritz@sol.at
Created: 26. Dez. 2004
Last modified: 01. Jän. 2005
License: free
Requirements: Python2.3
Exports: Drawer, Elem, Digit, Point, DPoint, Segments
"""
class Drawer(object):
""" Baseclass for interface to the drawing_area or canvas to draw at """
def __init__(self, *data, **kw):
super(Drawer, self).__init__()
def poly(self, points, color):
""" redefine this in your own Drawerclass """
raise NotImplemented("poly() is not implemented in baseclass!")
def rect(self, x, y, w, h, color):
self.poly(((x, y), (x, y+h), (x+w, y+h), (x+w, y)), color)
class ElemType(type):
__classes = {}
def classes(cls):
return cls.__classes
classes = property(classes)
def __init__(cls, name, bases, dct):
super(ElemType, cls).__init__(name, bases, dct)
for key in dct["idkey"]:
if cls.__classes.has_key(key):
raise ValueError("'%s' already used!" % key)
cls.__classes[key] = cls
def create(cls, key, *args, **kw):
return cls.__classes[key](*args, **kw)
def calc_size(cls, fmt, scale):
w = 0
h = []
for ch in fmt:
tmp = cls.create(ch, " ")
w += tmp.width * scale
h += [tmp.height * scale]
return w, max(h)
class Elem(object):
__metaclass__ = ElemType
idkey = ""
values = ""
shape = {"" : ()}
llcd = {"" : ()}
def __get_value(self):
return self.__value
def __set_value(self, value):
if not value in self.values:
msg = "value can only be one of '%s' not '%s!'"
raise ValueError(msg % (self.values, value))
try:
if value == self.__value:
return
old = self.llcd[self.__value]
except AttributeError:
old = None
self.__value = value
if self.drawer:
self.redraw(old)
value = property(__get_value, __set_value)
def get_width(self):
max_x = 0
for poly in self.shape.itervalues():
max_x = max([a for a, b, in poly] + [max_x])
return (max_x + 1) * self.scale
width = property(get_width)
def get_height(self):
max_y = 0
for poly in self.shape.itervalues():
max_y = max([b for a, b, in poly] + [max_y])
return (max_y + 1) * self.scale
height = property(get_height)
def get_xoffset(self):
xoffset = self.parent.x
if self.parent is not None:
for seg in self.parent:
if seg is self:
break
xoffset += seg.width
return xoffset
xoffset = property(get_xoffset)
def get_yoffset(self):
return self.parent.y
yoffset = property(get_yoffset)
def __init__(self, value="", scale=1, parent=None, drawer=None,
on_color="#00ff00", off_color="#002200", bg_color="#000000"):
super(Elem, self).__init__()
self.scale = scale
self.parent = parent
self.drawer = drawer
self.on_color = on_color
self.off_color = off_color
self.bg_color = bg_color
self.rescale()
self.value = value
def move(self, pts):
xoffset = self.xoffset
yoffset = self.yoffset
return [(a + xoffset, b + yoffset) for a, b in pts]
def redraw(self, old=None):
if self.drawer is None:
return
if old is None:
old = self.polys.keys()
for i in old:
self.drawer.poly(self.move(self.polys[i]),
self.on_color)
for i in [i for i in old if i not in self.llcd[self.value]]:
self.drawer.poly(self.move(self.polys[i]), self.off_color)
for i in [i for i in self.llcd[self.value] if i not in old]:
self.drawer.poly(self.move(self.polys[i]), self.on_color)
def set_drawer(self, drawer):
self.drawer = drawer
self.redraw()
def rescale(self):
scale = self.scale
self.polys = {}
for key, value in self.shape.iteritems():
self.polys[key] = [(a * scale, b * scale) for a, b, in value]
class Digit(Elem):
idkey = "#"
values = "0123456789E+-* "
# - b
# |,| ahc
# - g
# |'| fid
# - e
# polygon coordinates for height=50
shape = {
'a' : (( 1, 6), ( 3, 4), ( 5, 6), ( 5,16), ( 3,18), ( 1,16)),
'b' : (( 6, 1), (16, 1), (18, 3), (16, 5), ( 6, 5), ( 4, 3)),
'c' : ((17, 6), (19, 4), (21, 6), (21,16), (19,18), (17,16)),
'd' : ((17,22), (19,20), (21,22), (21,32), (19,34), (17,32)),
'e' : (( 6,33), (16,33), (18,35), (16,37), ( 6,37), ( 4,35)),
'f' : (( 1,22), ( 3,20), ( 5,22), ( 5,32), ( 3,34), ( 1,32)),
'g' : (( 6,17), (16,17), (18,19), (16,21), ( 6,21), ( 4,19)),
'h' : (( 9,16), ( 9,14), (11,12), (13,14), (13,16)),
'i' : (( 9,22), ( 9,24), (11,26), (13,24), (13,22)),
}
# llcd defines a list of segments to turn on for any particular symbol.
llcd = {
'0' : "abcdef",
'1' : "cd",
'2' : "bcefg",
'3' : "bcdeg",
'4' : "acdg",
'5' : "abdeg",
'6' : "abdefg",
'7' : "bcd",
'8' : "abcdefg",
'9' : "abcdeg",
'-' : "g",
'+' : "ghi",
'E' : "abefg",
' ' : "",
'*' : "abcdefghi"
}
class Point(Elem):
idkey = "."
values = ". "
shape = {"a" : (( 1,37), ( 1,33), ( 5,33), ( 5,37))}
llcd = {"." : "a", " " : ""}
class DPoint(Elem):
idkey = ":"
values = ": "
shape = {"a" : (( 1,16), ( 1,12), ( 5,12), ( 5,16)),
"b" : (( 1,26), ( 1,22), ( 5,22), ( 5,26))}
llcd = {":" : "ab", " " : ""}
class Segments(list):
def get_values(self):
return [x.value for x in self]
def set_values(self, values):
for elem, value in zip(self, values):
elem.value = value
values = property(get_values, set_values)
def get_fmt(self):
return self.__fmt
fmt = property(get_fmt)
def get_x(self):
return self.__x
x = property(get_x)
def get_y(self):
return self.__y
y = property(get_y)
def get_width(self):
return sum([elem.width for elem in self])
width = property(get_width)
def get_height(self):
return max([elem.height for elem in self])
height = property(get_height)
def __init__(self, fmt, values, drawer=None, scale=1, x=0, y=0,
on_color="#00ff00", off_color="#002200", bg_color="#000000"):
super(Segments, self).__init__()
self.__x = x
self.__y = y
self.__fmt = fmt
self.drawer = drawer
self.bg_color = bg_color
for key, value in zip(fmt,values):
self.append(Elem.create(key, value, scale, self, drawer,
on_color, off_color, bg_color))
def redraw(self):
self.drawer.rect(self.x, self.y,
self.width, self.height,
self.bg_color)
for elem in self:
elem.redraw()
def calc_size(fmt, scale):
return Elem.calc_size(fmt, scale)
calc_size = staticmethod(calc_size)
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
Modul: gtk_clock
Description: Clock with big sevensegmentdisplay
Version: 0.1
Copyright: 2004 by Fritz Cizmarov fritz@sol.at
Created: 01. Jän. 2005
Last modified: 01. Jän. 2005
License: free
Requirements: Python2.3
"""
import time
import pygtk
pygtk.require('2.0')
import gtk
import gobject
from SevenSegs import Drawer, Segments
class gtkDrawer(Drawer):
""" interface zu draw filled polygons on an drawable """
def __init__(self, drawable, colormap):
self.drawable = drawable
self.colormap = colormap
self.gc = drawable.new_gc()
black = self.colormap.alloc_color("#000000")
self.colors = {"#000000" : black}
def poly(self, points, color):
""" draw the Poly with pointlist points and color """
if color not in self.colors:
self.colors[color] = self.colormap.alloc_color(color)
self.gc.set_foreground(self.colors[color])
self.drawable.draw_polygon(self.gc, gtk.TRUE, points)
"""
def rect(self, x, y, w, h, color):
if color not in self.colors:
self.colors[color] = self.colormap.alloc_color(color)
self.gc.set_foreground(self.colors[color])
self.drawable.draw_rectangle(self.gc, gtk.TRUE, x, y, w, h)
"""
class APP(object):
def __init__(self):
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.window.connect("delete_event", self.delete_event)
self.window.connect("destroy", self.destroy)
self.window.set_resizable(gtk.FALSE)
self.window.set_position(gtk.WIN_POS_CENTER)
self.scale = 10
self.drawing_area = gtk.DrawingArea()
sc_width = gtk.gdk.screen_width()
while self.scale:
x, y = Segments.calc_size("##:##:##", self.scale)
if x+20 < sc_width:
break
self.scale -= 1
width = x + self.scale*4
height = y + self.scale*4
self.drawing_area.set_size_request(width, height)
self.drawing_area.connect("expose-event", self.area_expose_cb)
self.drawing_area.show()
self.window.add(self.drawing_area)
self.window.show()
gobject.timeout_add(1000, self.do_clock)
def area_expose_cb(self, area, event):
if not hasattr(self, "segments"):
self.drawer = gtkDrawer(area.window, area.get_colormap())
xoffset = self.scale*2
yoffset = self.scale*2
self.segments = Segments("##:##:##", "00:00:00", self.drawer,
self.scale, xoffset, yoffset)
w, h = self.drawer.drawable.get_size()
self.drawer.rect(0, 0, w, h, "#000000")
self.segments.redraw()
def delete_event(self, widget, event, data=None):
#print "delete_event occured"
return gtk.FALSE
def destroy(self, widget, date=None):
gtk.main_quit()
def do_clock(self):
if hasattr(self, "segments"):
self.segments.values = time.strftime("%H:%M:%S")
return True
def main_loop(self):
gtk.main()
app = APP()
app.main_loop()
Vielleicht hat ja wer lust, noch Beispiele für gt oder wxwidgets oder ... zu machen.
Gruß und gutes neues Jahr,
Dookie
Edit, kleine Änderungen am Code