simple graphics

D

db

Hi all,

I've mostly used python for database programming & file scripting. As such I
haven't had much need for graphics. Now I need to create a simple grid of
colored squares and change the colors in response to simple scripts I've
written. I'm wondering what your experiences have been with graphics in
Python & if there are any learning resources you know of that I can access
on the web or in a book.

Thanks! -DB
 
A

Anton Vredegoor

db said:
I've mostly used python for database programming & file scripting. As such I
haven't had much need for graphics. Now I need to create a simple grid of
colored squares and change the colors in response to simple scripts I've
written. I'm wondering what your experiences have been with graphics in
Python & if there are any learning resources you know of that I can access
on the web or in a book.

Here's an example vector graphics script using tkinter. Maybe you can
adapt it to your needs or extract some techniques out of it.

Anton.

# polyedit.py by Anton vredegoor <[email protected]> Oct 7, 2003
"""
This is a test version of a polygon editor. The script
displays a window with a grid of colored squares. Individual
squares can be selected and deselected with a mouseclick.

After *three or more* squares are selected a click with the
other mouse button makes a polygon visible. Another click
with this button hides the polygon again. Hiding the polygon
is sometimes necessary to access squares "under" it.

Functionality:

requirements: Python 2.3 with Tkinter (standard installation)
usage: just run the script with no arguments

button1: (left mouse button) selects/deselects squares
button3: (right mouse button) shows/hides the polygon
(at least 3 squares need to be selected to be able
to draw a polygon)

key "c": clear all entered data
key "p": print self.n and the list of selected polygons
key "ESC": exit application

Notes:

- by changing the number in function "main":
a = PolyEdit(root,10) it is possible to get more or less squares
displayed. (this number is also the first number that is printed
after pressing "p")
- since this is a vector graphic application, resizing the
application window will also resize and center the squares inside
the window
- the exact order in with the squares are selected is important,
deselecting the polygons in reverse order can be usefull
sometimes

Example polyedit output:

10 [(4, 5), (3, 3), (5, 4), (3, 5), (4, 3), (5, 5), (3, 4),
(5, 3)]
10 [(2, 2), (2, 6), (7, 6), (7, 5), (3, 5), (3, 3), (5, 3),
(5, 7), (6, 7), (6, 2)]
"""

from __future__ import division
from Tkinter import *

class AB(tuple):
""" groups values by two, access is by property a or b"""
def __new__(cls, *args):
return tuple.__new__(cls, args)
def geta(self): return self[0]
def getb(self): return self[1]
a,b = map(property,[geta,getb])

class Scaler(AB):
""" maps values from one coordinate system to another"""

def __init__(self, *args):
a,b = self.a,self.b
fx = (b.b.a-b.a.a)/(a.b.a-a.a.a)
fy = (b.b.b-b.a.b)/(a.b.b-a.a.b)
f = min(fx,fy)
wxc = (a.a.a+a.b.a)/2
wyc = (a.a.b+a.b.b)/2
vxc = (b.a.a+b.b.a)/2
vyc = (b.a.b+b.b.b)/2
xc = vxc-f*wxc
yc = vyc-f*wyc
self.f,self.xc,self.yc = f,xc,yc

def scalepoint(self, P):
f,xc,yc = self.f,self.xc,self.yc
return AB(f*P.a+xc, f*P.b+yc)

def scalerect(self, R):
f,xc,yc = self.f,self.xc,self.yc
p1 = AB(f*R.a.a+xc, f*R.a.b+yc)
p2 = AB(f*R.b.a+xc, f*R.b.b+yc)
return AB(p1,p2)

class PolyEdit:
""" tkinter application to edit polygons"""

def __init__(self, master,n):
self.n=n
self.canvas = Canvas(master,width=500,height=500)
self.canvas.pack(fill= BOTH, expand=YES)
master.bind("<Escape>", lambda event='ignored',
m=master: m.destroy())
master.bind("<Configure>", self.configure)
master.bind("<Key-p>", self.output)
master.bind("<Key-c>", self.clear)
self.canvas.bind("<Button-1>", self.toggleselect)
self.canvas.bind("<Button-3>", self.togglepoly)
self.rects = [self.canvas.create_rectangle(0,0,0,0)
for i in range(n) for j in range(n)]
self.polypoints = []
self.polygons = []
self.polyshown = False

def output(self,event=None):
print self.n,self.polypoints

def togglepoly(self,event=None):
if self.polyshown: self.hidepoly()
else: self.showpoly()

def hidepoly(self,event=None):
for x in self.polygons:
self.canvas.delete(x)
self.polyshown = False

def clear(self,event=None):
c = self.canvas
self.hidepoly()
self.polypoints = []
self.polygons = []
rects = c.find_withtag("selected")
for r in rects:
c.dtag(r,"selected")
c.itemconfig(r,fill = "yellow")

def toggleselect(self,event):
c,x,y = self.canvas,event.x, event.y
cvid = c.find_closest(x,y)
if cvid[0] in self.rects:
i,j = divmod(cvid[0]-1,self.n)
if "selected" in c.gettags(cvid):
c.dtag(cvid,"selected")
c.itemconfig(cvid,fill = "yellow")
self.polypoints.remove((i,j))
else:
c.itemconfig(cvid,tags = ("selected"),
fill = "red")
self.polypoints.append((i,j))
if self.polyshown:
self.hidepoly()
self.showpoly()

def configure(self, event):
self.draw()

def draw(self):
polyshown = self.polyshown
self.hidepoly()
c = self.canvas
scale = Scaler(self.b,self.a)
for rect in self.rects:
i,j = divmod(rect-1,self.n)
r = scale.scalerect(AB(AB(i,j),AB(i+1,j+1)))
c.coords(rect,r.a.a,r.a.b,r.b.a,r.b.b)
if "selected" in c.gettags(rect):
c.itemconfig(rect,fill = "red")
else:
c.itemconfig(rect,fill = "yellow")
if polyshown: self.showpoly()

def showpoly(self,event=None):
c = self.canvas
scale = Scaler(self.b,self.a)
pts = []
if len(self.polypoints)>2:
for i,j in self.polypoints:
pts.append(scale.scalepoint(AB(i+.5,j+.5)))
self.polygons.append(c.create_polygon(pts,
fill="black"))
self.polyshown = True

def geta(self):
c = self.canvas
p1 = AB(0,0)
p2 = AB(c.winfo_width(), c.winfo_height())
return AB(p1,p2)

def getb(self):
p1 = AB(0,0)
p2 = AB(self.n,self.n)
return AB(p1,p2)

a,b = map(property,[geta,getb])

def main():
root = Tk()
root.title('Polygon Editor')
a = PolyEdit(root,10)
root.mainloop()

if __name__=='__main__':
main()
 
J

John J. Lee

db said:
I've mostly used python for database programming & file scripting. As such I
haven't had much need for graphics. Now I need to create a simple grid of
colored squares and change the colors in response to simple scripts I've
written. I'm wondering what your experiences have been with graphics in
Python & if there are any learning resources you know of that I can access
on the web or in a book.

Vector or bitmap?

Bitmap: PIL.

Vector: Reportlab, PIDDLE, Sketch.

(Of course, the categories overlap a bit...)

If this is for the web, you might just use some HTML tables instead --
no need for bitmaps. Should be quite easy to do with HTML and a bit
of JavaScript, actually.


John
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,175
Latest member
Vinay Kumar_ Nevatia
Top