I've worked on this table object a bit too long - and seem to have
stared too long at the code. Can someone see where it goes wrong in
the insertrow function?
Also optimization hints and alternatives will be greatly appreciated.
<code>
#!env python
#
# created: "15:19 20/01-2004" by Kim Petersen <ki*@vindinggaa rd.dk>
#
# $Id$
#
import Tkinter
class UserDict:
defaults={}
def __init__(self,i nherit=None):
if not inherit:
self.inherit=[]
else:
self.inherit=in herit
self.dict=self. defaults.copy()
def __setitem__(sel f,name,value): self.dict[name]=value
def __getitem__(sel f,name):
if not self.dict.has_k ey(name):
for dict in self.inherit:
if dict.has_key(na me):
return dict[name]
raise KeyError,"%s not found" % (name,)
return self.dict[name]
def haskey(self,nam e): return self.dict.has_k ey(name)
class Cell(UserDict):
defaults={"widt h": 0,"height": 0,"text": '',"color": "black","backgr ound": "white",
"widgets": None}
def __init__(self,m aster,row,colum n,text):
UserDict.__init __(self,[row,column])
self.master=mas ter
self["text"]=text
self.row=row # these are needed for us to find the actual row/col
self.column=col umn
self.create()
def create(self):
"""Create the widgets the first time (might inflict up to two resize's)"""
x,y=self.column["x"],self.row["y"]
w,h=self.column["width"],self.row["height"]
r=self.master.c reate_rectangle ((x,y,x+w,y+h), fill=self["background "])
t=self.master.c reate_text((x+s elf.master.colp adding,y+h/2),
text=self["text"],
anchor="w",fill =self["color"])
self["widgets"]=[r,t]
bbox=self.maste r.bbox(t)
self["width"]=bbox[2]-bbox[0]
self["height"]=bbox[3]-bbox[1]
if self["width"]+self.master.co lpadding*2>w:
self.column.res ize(self["width"]+self.master.co lpadding*2)
self.resize()
if self["height"]+self.master.ro wpadding*2>h:
self.row.resize (self["height"]+self.master.ro wpadding*2)
self.resize()
def resize(self):
"""Resize according to the width/height given by row,column"""
x,y=self.column["x"],self.row["y"]
w,h=self.column["width"],self.row["height"]
self.master.coo rds(self["widgets"][0],(x,y,x+w,y+h))
self.master.coo rds(self["widgets"][1],(x+self.master .colpadding,y+h/2))
def move(self,dx,dy ):
"""Relative ly move according to delta's"""
self.master.mov e(self["widgets"][0],dx,dy)
self.master.mov e(self["widgets"][1],dx,dy)
class Column(UserDict ):
""" """
defaults={"x": 0,"width": 0,"label": '',"tag": ''}
def __init__(self,m aster,label='', before=None):
UserDict.__init __(self)
self.master=mas ter
if master.columns:
if not before or before>0:
if not before:
after=(-1)
else:
after=before-1
self.dict["x"]=master.columns[after]["x"]+master.columns[after]["width"]
# since we have a width of 0 there is no need to move the rest of the columns.
def calcwidth(self) :
"""Calculat e the *actually* needed width of the column (*not* the current one)."""
width=0
for row in self.master.row s:
width=max(self. master.cells[(row,self)]["width"],width)
return width+self.mast er.colpadding*2
def resize(self,wid th):
# calc delta, set new width
dx=width-self["width"]
self["width"]=width
ci=self.master. columns.index(s elf)
# resize the cells
for row in self.master.row s:
try:
self.master.cel ls[(row,self)].resize()
except KeyError:
pass
# move columns to the right further to the right
for i in range(ci+1,len( self.master.col umns)):
self.master.col umns[i].move(dx)
def move(self,dx):
self["x"]=self["x"]+dx
# move the cells correspondingly
for row in self.master.row s:
try:
self.master.cel ls[(row,self)].move(dx,0)
except KeyError:
pass
class Row(UserDict):
defaults={"y": 0,"height": 0,"label": '',"tag": ''}
def __init__(self,m aster,label,bef ore=None):
UserDict.__init __(self)
self["label"]=label
# now insert it.
self.master=mas ter
if master.rows:
if not before or before>0:
if not before:
after=(-1)
else:
after=before-1
self.dict["y"]=master.rows[after]["y"]+master.rows[after]["height"]
def calcheight(self ):
"""Calculat e the *actually* needed width of the column (*not* the current one)."""
height=0
for row in self.master.col umns:
height=max(self .master.cells[(self,column)]["height"],height)
return height+self.mas ter.rowpadding* 2
def resize(self,hei ght):
dy=height-self.dict["height"]
self.dict["height"]=height
ri=self.master. rows.index(self )
for column in self.master.col umns:
if self.master.cel ls.has_key((sel f,column)):
self.master.cel ls[(self,column)].resize()
for i in range(ri+1,len( self.master.row s)):
self.master.row s[i].move(dy)
def move(self,dy):
self.dict["y"]=self.dict["y"]+dy
for col in self.master.col umns:
try:
self.master.cel ls[(self,col)].move(0,dy)
except KeyError:
pass
pass
def moveto(self,y):
self.move(y-self.dict["y"])
def __setitem__(sel f,name,value):
if name=="height":
self.resize(val ue)
elif name=="y":
self.move(value-self["y"])
else:
self.dict[name]=value
class Table(Tkinter.C anvas):
"""A table object - it consists of a number of cells layed out in rows and columns
A row has a specific height
A row can have a label
A column has a specific width
A column can have a label
"""
def __init__(self,m aster,**args):
Tkinter.Canvas. __init__(self,m aster,**args)
self.colpadding =2
self.rowpadding =2
self.columns=[] # each item contains data about the column
self.rows=[] # each item contains data about the row
self.cells={} # index: (row,col)
def insertrow(self, pos,values):
self.rows[pos:pos]=[Row(self,'',pos )]
row=self.rows[pos]
for i in range(len(value s)):
if i<len(self.colu mns):
col=self.column s[i]
else:
self.columns.ap pend(Column(sel f,''))
col=self.column s[-1]
self.cells[(row,col)]=Cell(self,row, col,values[i])
def row_add(self,va lues):
self.rows.appen d(Row(self,''))
row=self.rows[-1]
for i in range(len(value s)):
if i<len(self.colu mns):
col=self.column s[i]
else:
self.columns.ap pend(Column(sel f,''))
col=self.column s[-1]
self.cells[(row,col)]=Cell(self,row, col,values[i])
if __name__=="__ma in__":
tk=Tkinter.Tk()
tk.grid_rowconf igure(1,weight= 1)
tk.grid_columnc onfigure(1,weig ht=1)
tk.wm_geometry( "800x1150+0 +0")
table=Table(tk)
table.grid(row= 1,column=1,stic ky="nsew")
for line in open("/etc/passwd","r"):
values=unicode( line.strip(),"i so8859-1").split(": ")
#tk.update()
#table.insertro w(0,values)
table.row_add(v alues)
for row in table.rows:
print row["y"],row["height"]
tk.mainloop()
# Local Variables:
# tab-width: 3
# py-indent-offset: 3
# End:
</code>
--
Privat =============== =========== Kim Petersen =============== ===== Arbejde
Email ki*@vindinggaar d.dk ===== Jens Grøns Vej 11 ===== Email ki*@lignus.dk
Tlf +45 75 83 15 50 ============== 7100 Vejle ========= Tlf +45 75 83 15 51
Fax +45 75 83 15 62 ============= DK - Danmark ======== Fax +45 75 83 15 62