beim Setzen von Zellenwerten wird immer die Zelle in der letzten Zeile gesetzt, dh. die Spalte passt, aber die zeilennummer ist falsch.
Hoffe von Euch siehts jemand schneller als ich. Danke
Hier der Code:
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import sys
import ttk
# Setup the Logging - System:
import logging
Logger = logging.getLogger(__name__) # so Logger is unique
Logger.setLevel(logging.NOTSET) # no level at develtime
Logger.addHandler(logging.NullHandler()) # no destination of ...
ENC = "utf-8"
class MyTableError(ValueError): pass
class MyTableOptionError(ValueError): pass
class Table(object):
"""
>>> root = ttk.Tkinter.Tk()
>>> tabelle = Table(root,
>>> 3,
>>> 4,
>>> width=[5,10,3,12,9,8,10,11, 9, 12],
>>> columnhead=True,
>>> columnheads=["S1", "S2", "S3", "S4"],
>>> rowhead=True,
>>> rowheads=[
>>> "Dataset 1:",
>>> "Dataset 2:",
>>> "Dataset 3:"],
>>> entrybg="#ABC",
>>> labelbg="#234567"
>>> )
>>> # teste setCell
>>> zelle = tabelle.setCell(1,2,"ADF")
>>>
>>> root.mainloop()
"""
def __init__(self, parent, rows, columns, **kwargs):
_c = "<%s>" % (self.__class__.__name__,)
Logger.debug(_c)
try:
top = parent.winfo_toplevel()
except:
err = "%s need a tkinter object to draw on!" % (_c, )
Logger.exception(err)
raise ValueError(err)
try:
rows = abs(int(rows))
columns = abs(int(columns))
except Exception:
err = "%s rows and columns need integer values or values " % (_c,)
err += "convertable to integer!"
Logger.exception(err)
raise ValueError(err)
if rows == 0:
err = "%s you set the row counter to 0!" % (_c,)
Logger.exception(err)
raise ValueError(err)
elif columns == 0:
err = "%s you set the column counter to 0!" % (_c,)
Logger.exception(err)
raise ValueError(err)
self.parent = parent
self.rows = rows + 1 # + column header
self.columns = columns + 1 # + row header
self.frm = ttk.Tkinter.Frame(self.parent)
# Datamodel with header
zeile = [None, ]*self.columns
self._matrix = [zeile,]*self.rows
self.options = {
"vartype": "s",
"columnhead": False,
"columnheads": ["", ] + range(self.columns),
"rowhead": False,
"rowheads": ["", ] + range(self.rows),
"width": [1,] + [10,]*(self.columns-1),
"entrystyle": "sunken",
"entrybg": "#FFF",
"labelstyle": "groove",
"labelbg": "#AAA"
}
self.setOptions(**kwargs)
self.setup()
self.frm.pack()
Logger.info("%s done", _c)
def setOptions(self, **kwargs):
_c = "<%s>" % (self.__class__.__name__,)
Logger.debug(_c)
def raiseerror(key="", value="", err="option %s has wrong value %s"):
if key and value:
txt = err % (key, value)
elif key:
txt = err % (key,)
elif value:
txt = err % (value,)
else:
txt = err
Logger.exception(txt)
raise MyTableOptionError(txt)
# check options
Logger.debug("%s check option %s [value=%s]")
for k,v in kwargs.items():
Logger.debug("%s set option %s [value=%s]", _c, k, v)
if k.lower() not in self.options.keys():
raiseerror(k,v)
# pruefen der einzelnen Optionen
k = k.lower()
if k == "rowhead" or k == "columnhead":
try:
self.options[k] = bool(kwargs[k])
except:
raiseerror(k,v)
elif k == "columnheads" or k == "rowheads":
if type(v).__name__ not in ["list", "tuple"]:
err = "option %s needs a sequence type [got %s instead]"
raiseerror(k, type(v).__name__, err)
if k == "columnheads":
if len(v) < self.columns - 1:
err = "%s column header needed! Got only %s"
raiseerror(self.columns - 1, len(v), err)
self.options[k] = ["",] + v[:self.columns - 1]
elif k == "rowheads":
if len(v) < self.rows - 1:
err = "%s row header needed! Got only %s"
raiseerror(self.rows - 1, len(v), err)
v = v[:self.rows - 1]
self.options[k] = ["",] + v
# calculate width of rowheads
self.options["width"][0] = max([len(str(r)) for r in v])
elif k == "vartype":
s = [str,unicode,"str","string","s", "u","unicode"]
i = [int, long, "long", "l", "int", "i",]
f = [float, "float", "f"]
if v not in s + i + f:
svt = [str(v) for v in vartypes]
svt = ", ".join(svt)
raiseerror(k,svt,"valid values for %s are [%s]")
if v in s:
self.options[k] = "s"
elif v in i:
self.options[k] = "i"
elif v in f:
self.options[k] = "f"
elif k == "width":
if type(v).__name__ in ["int", "float", "long"]:
self.options.update({k: [int(v),]*self.columns})
elif type(v).__name__ in ["list", "tuple"]:
if len(v) < self.columns - 1:
raiseerror(err="to few width values")
else:
rheadwidth = [self.options["width"][0],]
colwidth = [int(_v) for _v in v[:self.columns-1]]
self.options.update({k: rheadwidth + colwidth})
else:
raiseerror(err="unkown type for width")
elif k == "entrystyle" or k == "labelstyle":
styles = ["flat","raised","sunken","groove","ridge"]
if v.lower() not in styles:
s = ", ".join(styles)
err = "valid styles are [%s], got %s" % (s, str(v))
raiseerror(err=err)
self.options[k] = v.lower()
elif k == "entrybg" or k == "labelbg":
if v[0] == "#":
valids = "0123456789ABCDEF"
for l in v[1:]:
if l not in valids:
raiseerror(k,v)
v = v.upper()
else:
valids = ["white", "black", "red", "green", "blue",
"cyan", "yellow", "magenta" ]
if v not in valids:
raiseerror(k,v)
v = v.lower()
self.options[k] = v
else:
raiseerror(k, err="unknown option %s!")
Logger.debug("%s ...checked", _c)
Logger.info("%s set options: ", _c)
for k,v in self.options.items():
Logger.info("%s - %s: %s", _c,k,v)
def setupLabel(self, frm, width=10, text=""):
return ttk.Tkinter.Label(frm,
width=width,
text=text,
relief=self.options["labelstyle"],
bg=self.options["labelbg"],
)
def setupColheader(self, columnheads=[]):
_c = "<%s>" % (self.__class__.__name__,)
Logger.debug(_c)
if columnheads:
setOptions(columnhead=True, columnheads=rowheads)
if self.options["columnhead"]:
for i, col in enumerate(self._matrix[0]):
col = self.setupLabel(self.frm,
width=self.options["width"][i],
text=self.options["columnheads"][i],
)
col.grid(row=0, column=i)
Logger.debug("columnheader created")
else:
Logger.debug("no columnheader wanted")
def setupRowheader(self, rowheads=[]):
_c = "<%s>" % (self.__class__.__name__,)
Logger.debug(_c)
if rowheads:
setOptions(rowhead=True, rowheads=rowheads)
if self.options["rowhead"]:
for i, row in enumerate(self._matrix):
row[0] = self.setupLabel(self.frm,
width=self.options["width"][0],
text=self.options["rowheads"][i],
)
row[0].grid(row=i, column=0)
Logger.debug("rowheader created")
else:
Logger.debug("no rowheader wanted")
def setup(self):
_c = "<%s>" % (self.__class__.__name__,)
Logger.debug(_c)
self.setupColheader()
self.setupRowheader()
weiten = self.options["width"]
for z in range(1, self.rows):
for s in range(1, self.columns):
if self.options["vartype"] == "s":
v = ttk.Tkinter.StringVar()
elif self.options["vartype"] == "i":
v = ttk.Tkinter.IntVar()
elif self.options["vartype"] == "f":
v = ttk.Tkinter.DoubleVar()
e = ttk.Tkinter.Entry(self.frm,
width=self.options["width"][s],
relief=self.options["entrystyle"],
bg=self.options["entrybg"],
textvar=v,
)
e.grid(row=z, column=s)
self._matrix[z][s] = (v,e)
Logger.debug("%s cell [row=%s, col=%s] created", _c, z, s)
Logger.debug("%s row %s created", _c, z)
Logger.debug("%s cells created", _c)
def getCell(self, row, column, entry=False):
"""
:param row: {1 <= row <= rowcounter}
:param column: {1 <= column <= rowcounter}
"""
_c = "<%s>" % (self.__class__.__name__,)
Logger.debug(_c)
if not (1 <= row < self.rows):
_c = "<%s>" % (self.__class__.__name__,)
err = "%s valid row values between 1 and %s" % (_c, self.rows - 1)
Logger.exception(err)
raise MyTableError(err)
if not (1 <= column < self.columns):
_c = "<%s>" % (self.__class__.__name__,)
err = "%s valid column values between 1 and %s" \
% (_c,self.columns-1)
Logger.exception(err)
raise MyTableError(err)
if entry:
_cell = self._matrix[row][column][1]
else:
_cell = self._matrix[row][column][0].get()
Logger.info("%s return: %s", _c, _cell)
return _cell
def getRow(self, row, entry=False):
_c = "<%s>" % (self.__class__.__name__,)
Logger.debug(_c)
_row = []
for column in range(1, self.columns):
_row.append( self.getCell(row, column, entry) )
Logger.info("%s return: [%s]", _c, _row)
return _row
def get(self, entry=False):
_c = "<%s>" % (self.__class__.__name__,)
Logger.debug(_c)
_matrix = []
for r in range(1, self.rows):
_matrix.append( self.getRow(r) )
Logger.info("%s return: %s", _c, _matrix)
return _matrix
def setCell(self, row, column, value):
_c = "<%s>" % (self.__class__.__name__,)
Logger.debug("%s set [row=%s, column=%s] to %s", _c,row,column,value)
if not (1 <= row < self.rows):
_c = "<%s>" % (self.__class__.__name__,)
err = "%s valid row values between 1 and %s" % (_c, self.rows - 1)
Logger.exception(err)
raise MyTableError(err)
if not (1 <= column < self.columns):
_c = "<%s>" % (self.__class__.__name__,)
err = "%s valid column values between 1 and %s" \
% (_c,self.columns-1)
Logger.exception(err)
raise MyTableError(err)
self._matrix[row][column][0].set( value )
Logger.info("%s [row=%s, column=%s]=%s", _c, row, column, value)
def __unicode__(self):
_c = "<%s>" % (self.__class__.__name__,)
Logger.debug(_c)
weiten = self.options["width"][1:]
trenner = tuple(["-"*w for w in weiten])
fmt = ["{:-<%s}" % (w,) for w in weiten]
fmttr = u"+-%s-+" % ("-+-".join(fmt),)
tr = fmttr.format(*trenner)
fmt = ["{:<%s}" % (w,) for w in weiten]
fmt = u"| %s |" % (" | ".join(fmt),)
out = u""
for r in range(1, self.rows):
zeile = tuple(self.getRow(r))
out += tr + os.linesep + fmt.format(*zeile) + os.linesep
return out + tr
def __str__(self):
return self.__unicode__().encode(ENC)
def test():
root = ttk.Tkinter.Tk()
zeilen = 3
spalten = 4
tabelle = Table(root,
zeilen,
spalten,
width=[5,10,4,12,9,8,10,11, 9, 12],
columnhead=True,
columnheads=["S1", "S2", "S3", "S4"],
rowhead=True,
rowheads=[
"Datensatz 1:",
"Datensatz 2:",
"Datensatz 3:"],
entrybg="#ABC",
labelbg="#234567"
)
for i, z in enumerate(tabelle._matrix[1:]):
print "Zeile %s: " % str(i + 1),
print z
tabelle.setCell(1,1, "ASDF")
print tabelle
root.mainloop()
return 0
if __name__ == "__main__":
sys.exit(test())