468,288 Members | 1,985 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,288 developers. It's quick & easy.

tkinter drawing

I want to be able to easily create reusable shapes in Tkinter and be
able to use them in mid level dialogs. So after some experimenting I've
managed to get something to work.

The following does pretty much what I need, but I think it can be
improved on. So could anyone take a look and let me know what you think?

Some of the things I want to add, but aren't exactly sure how at this time:
Nested groups
Use tags to be able to change sub items later
Have items get attribues from the group if it doesn't have them

Hope this isn't too long.

Cheers, Ron

Tkinter Color Vector Objects

Just the bare minimum to create re-sizable
and re-usable color icons in tkinter.

import Tkinter as Tk
import math

def getregpoly(sides):
""" Get points for a unit regular-polygon with n sides. """
points = []
ang = 2*math.pi / sides
for i in range(sides):
deg = (i+.5)*ang
return points

def scale(points, scale):
return [x*scale for x in points]

def move(points, x, y):
xy = [x,y]*(len(points)//2)
return [xy+coord for xy, coord in zip(xy,points)]

def translate(obj, x, y, zoom):
p = scale(obj.points, obj.size)
p = move(p, obj.x, obj.y)
p = scale(p, zoom)
return move(p, x, y)

def draw(obj, c, x=0 ,y=0, zoom=1):
p = translate(obj, x, y, zoom)
if obj.obj=='line':
c.create_line( p, fill=obj.fill, width=obj.width,
arrow=obj.arrow )
elif obj.obj=='rectangle':
c.create_line( p, fill=obj.fill, outline=obj.outline,
elif obj.obj=='polygon':
c.create_polygon( p, fill=obj.fill, outline=obj.outline,
width=obj.width, smooth=obj.smooth )
elif obj.obj=='text':
size = int(obj.size*zoom)
font = (obj.font,size,obj.style)
c.create_text(p, text=obj.text, font=font, fill=obj.fill)
elif obj.obj=='oval':
c.create_oval( p, fill=obj.fill, outline=obj.outline,
width=obj.width )
elif obj.obj=='arc':
c.create_arc( p, start=obj.start, extent=obj.extent,
style=obj.style, fill=obj.fill,
outline=obj.outline, width=obj.width )

class Shape(object):
size = 1
x = y = 0
def __init__(self, **kwds):
def __call__(self, *args, **kwds):
for key in self.__dict__:
if key not in kwds:
kwds[key] = self.__dict__[key]
return self.__class__(*args, **kwds)
def draw(self, c, x=0, y=0, scale=1.0):
draw(self, c, x, y, scale)

class Group(list):
obj = 'group'
def __init__(self, *args, **kwds):
self[:] = args
def __call__(self, *args, **kwds):
args = self[:]+list(args)
for key in self.__dict__:
if key not in kwds:
# make copies
kwds[key] = self.__dict__[key]()
return self.__class__(*args, **kwds)
def draw(self, c, x=0, y=0, scale=1.0):
for item in self:
item.draw(c, x, y, scale)
for key in self.__dict__:
self.__dict__[key].draw(c, x, y, scale)

# base shapes.
text = Shape( obj='text', text='', fill='black', width=0,
font='', style='', points=[0,0] )
line = Shape( obj='line', arrow='none', fill='black',
smooth='false', width=1, points=[0,0,1,0])
rectangle = Shape( obj='rectangle', fill='', outline='black',
width=1, points=[0,0,1,.5])
polygon = Shape( obj='polygon', fill='grey', outline='',
width=0, points=[0,0], smooth='false' )
oval = Shape( obj='oval', fill='grey', outline='',
width=0, points=[0,0,1,.75] )
arc = Shape( obj='arc', fill='grey', outline='', width=0,
style='arc', start='0', extent='90',

# shape variations
chord = arc(style='chord')
pie = arc(style='pieslice')
circle = oval(points=[0,0,1,1])
square = rectangle(points=[0,0,1,1])
triangle = polygon( points=getregpoly(3))
octagon = polygon( points=getregpoly(8))

caution = Group(
triangle(x=6, y=5, size=75),
triangle(size=75, fill='yellow'),
txt = text( text='!',
x=38, y=32, size=30,
font='times', style='bold') )

circlepart = chord( x=15, y=15, size=25, fill='red',
start='140', extent='155' )
error = Group(
octagon(x=6, y=5, size=56),
octagon(size=56, fill='red'),
circle(x=9, y=9, size=37, fill='white'),
circlepart(start='320') )

bubbletip = polygon(points=[34,42,60,56,50,38])
question = Group(
bubbletip(x=6, y=5),
oval(x=6, y=5, size=60),
oval(size=60, fill='lightblue'),
txt = text( text='?',
x=31, y=22, size=28,
font='times', style='bold' ) )
info = question()
info.txt.text = 'i'

if __name__ == '__main__':
root = Tk.Tk()
root.title('Resizable Shapes')
c = Tk.Canvas(root)


logo = caution() # get a copy
logo.txt = text( text='&', fill='#00bb44',
x=39, y=34, size=30 )

message = text( text="What's Your Size?",
size=15, fill='white' )
Group( message( x=1, y=1, fill='grey30'),
message() ).draw(c,190,235,2)

line( width=3, fill='darkgrey', arrow='both'


Oct 15 '05 #1
0 2523

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

2 posts views Thread by Matthew Wilson | last post: by
2 posts views Thread by Krzysztof Szynter | last post: by
8 posts views Thread by Erik Johnson | last post: by
3 posts views Thread by phil | last post: by
3 posts views Thread by Kevin Walzer | last post: by
7 posts views Thread by =?iso-8859-1?q?Xavier_B=E9rard?= | last post: by
5 posts views Thread by exhuma.twn | last post: by
reply views Thread by Nick Dumas | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.