ReusableShapes


   1 """
   2 Tkinter Color Vector Objects
   3 
   4 Just the bare minimum to create re-sizable
   5 and re-usable color icons in tkinter.
   6 - Ron Adam
   7 """
   8 
   9 import Tkinter as Tk
  10 import math
  11 
  12 def getregpoly(sides):
  13      """ Get points for a unit regular-polygon with n sides. """
  14      points = []
  15      ang = 2*math.pi / sides
  16      for i in range(sides):
  17          deg = (i+.5)*ang
  18          points.append(math.sin(deg)/2.0+.5)
  19          points.append(math.cos(deg)/2.0+.5)
  20      return points
  21 
  22 def scale(points, scale):
  23      return [x*scale for x in points]
  24 
  25 def move(points, x, y):
  26      xy = [x,y]*(len(points)//2)
  27      return [xy+coord for xy, coord in zip(xy,points)]
  28 
  29 def translate(obj, x, y, zoom):
  30      p = scale(obj.points, obj.size)
  31      p = move(p, obj.x, obj.y)
  32      p = scale(p, zoom)
  33      return move(p, x, y)
  34 
  35 def draw(obj, c, x=0 ,y=0, zoom=1):
  36      p = translate(obj, x, y, zoom)
  37      if obj.obj=='line':
  38          c.create_line( p, fill=obj.fill, width=obj.width,
  39                         arrow=obj.arrow )
  40      elif obj.obj=='rectangle':
  41          c.create_line( p, fill=obj.fill, outline=obj.outline,
  42                         width=obj.width)
  43      elif obj.obj=='polygon':
  44          c.create_polygon( p, fill=obj.fill, outline=obj.outline,
  45                            width=obj.width, smooth=obj.smooth )
  46      elif obj.obj=='text':
  47          size = int(obj.size*zoom)
  48          font = (obj.font,size,obj.style)
  49          c.create_text(p, text=obj.text, font=font, fill=obj.fill)
  50      elif obj.obj=='oval':
  51          c.create_oval( p, fill=obj.fill, outline=obj.outline,
  52                         width=obj.width )
  53      elif obj.obj=='arc':
  54          c.create_arc( p, start=obj.start, extent=obj.extent,
  55                        style=obj.style, fill=obj.fill,
  56                        outline=obj.outline, width=obj.width )
  57 
  58 class Shape(object):
  59      size = 1
  60      x = y = 0
  61      def __init__(self, **kwds):
  62          self.__dict__.update(kwds)
  63      def __call__(self, *args, **kwds):
  64          for key in self.__dict__:
  65              if key not in kwds:
  66                  kwds[key] = self.__dict__[key]
  67          return self.__class__(*args, **kwds)
  68      def draw(self, c, x=0, y=0, scale=1.0):
  69          draw(self, c, x, y, scale)
  70 
  71 class Group(list):
  72      obj = 'group'
  73      def __init__(self, *args, **kwds):
  74          self[:] = args
  75          self.__dict__.update(kwds)
  76      def __call__(self, *args, **kwds):
  77          args = self[:]+list(args)
  78          for key in self.__dict__:
  79              if key not in kwds:
  80                  # make copies
  81                  kwds[key] = self.__dict__[key]()
  82          return self.__class__(*args, **kwds)
  83      def draw(self, c, x=0, y=0, scale=1.0):
  84          for item in self:
  85              item.draw(c, x, y, scale)
  86          for key in self.__dict__:
  87              self.__dict__[key].draw(c, x, y, scale)
  88 
  89 # base shapes.
  90 text = Shape( obj='text', text='', fill='black', width=0,
  91                font='', style='', points=[0,0] )
  92 line = Shape( obj='line', arrow='none', fill='black',
  93                smooth='false', width=1, points=[0,0,1,0])
  94 rectangle = Shape( obj='rectangle', fill='', outline='black',
  95                     width=1, points=[0,0,1,.5])
  96 polygon = Shape( obj='polygon', fill='grey', outline='',
  97                   width=0, points=[0,0], smooth='false' )
  98 oval = Shape( obj='oval', fill='grey', outline='',
  99                width=0, points=[0,0,1,.75] )
 100 arc = Shape( obj='arc', fill='grey', outline='', width=0,
 101               style='arc', start='0', extent='90',
 102               points=[0,0,1,1])
 103 
 104 # shape variations
 105 chord = arc(style='chord')
 106 pie = arc(style='pieslice')
 107 circle = oval(points=[0,0,1,1])
 108 square = rectangle(points=[0,0,1,1])
 109 triangle = polygon( points=getregpoly(3))
 110 octagon = polygon( points=getregpoly(8))
 111 
 112 # CAUTION ICON
 113 caution = Group(
 114      triangle(x=6, y=5, size=75),
 115      triangle(size=75, fill='yellow'),
 116      txt = text( text='!',
 117                  x=38, y=32, size=30,
 118                  font='times', style='bold') )
 119 
 120 # ERROR ICON
 121 circlepart = chord( x=15, y=15, size=25, fill='red',
 122                      start='140', extent='155' )
 123 error = Group(
 124      octagon(x=6, y=5, size=56),
 125      octagon(size=56, fill='red'),
 126      circle(x=9, y=9, size=37, fill='white'),
 127      circlepart(),
 128      circlepart(start='320') )
 129 
 130 # QUESTION & INFO ICONS
 131 bubbletip = polygon(points=[34,42,60,56,50,38])
 132 question = Group(
 133      bubbletip(x=6, y=5),
 134      oval(x=6, y=5, size=60),
 135      bubbletip(fill='lightblue'),
 136      oval(size=60, fill='lightblue'),
 137      txt = text( text='?',
 138                  x=31, y=22, size=28,
 139                  font='times', style='bold' ) )
 140 info = question()
 141 info.txt.text = 'i'
 142 
 143 if __name__ == '__main__':
 144      root = Tk.Tk()
 145      root.title('Resizable Shapes')
 146      c = Tk.Canvas(root)
 147 
 148      caution.draw(c,40,20,.5)
 149      error.draw(c,120,20,1)
 150      question.draw(c,210,20,2)
 151      info.draw(c,50,100)
 152 
 153      logo = caution()  # get a copy
 154      logo.txt = text( text='&', fill='#00bb44',
 155                         x=39, y=34, size=30 )
 156      logo.draw(c,135,110,1.3)
 157 
 158      message = text( text="What's Your Size?",
 159                      size=15, fill='white' )
 160      Group( message( x=1, y=1, fill='grey30'),
 161             message() ).draw(c,190,235,2)
 162 
 163      line( width=3, fill='darkgrey', arrow='both'
 164            ).draw(c,20,205,336)
 165 
 166      c.pack()
 167      root.mainloop() 
 168 

tkinter: ReusableShapes (last edited 2011-12-07 21:18:51 by AnthonyMuss)