ich hab auch mal was probiert...
wenn man auf einen tag klickt, der nicht mehr in dem monat liegt, wechselt er automatisch *stolz-sei*
Code: Alles auswählen
import Tkinter as tk
class KalFrame(tk.Frame):
# Funktionen:
#
# _color_set
# _color_reset
# _zurueck
# _vor
# _markiere
# istSchaltjahr
# anz_tage
# JACOBSTHAL
# set_monat
# _auswahl
# get
from time import localtime
def __init__(self,master,fkt1=None,fkt2=None,*cnf,**opts):
tk.Frame.__init__(self,master,*cnf,**opts)
# vars:
self.farben={"bg1":"gray100",
"bg2":"gray88",
"bg3":"gray100",
"bg4":"darkblue",
"bg5":"lightblue",
"bgactive":"#05044A",
"bgbuttons":"gray88",
"bglabel":"gray88",
"bgweekend":"gray66",
"fg1":"gray88", # Markierung premonth (angeschnitten)
"fg2":"black", # Markierung Hauptmonat
"fg3":"gray88", # Markierung newmonth (angeschnitten)
"fg4":"white", # Markierung Termin/Event im Hauptmonat
"fg5":"black", # Markierung Termin/Event im Nebenmonat
"fgactive":"#ffA518", # Markierung wenn geklickt
"fgbuttons":"black", # Flaechenfarbe: Buttons (vor/zurueck)
"fglabel":"black", # Flaechenfarbe: Label (anz akt monat)
"fgweekend":"white"} # Markierung von Sa und So
self.fkt1 = fkt1
self.fkt2 = fkt2
self.bulist = []
self.m = 1 # aktueller monat
self.j = 2006 # aktuelles jahr
self.last_choosen_widget = -1
# start:
for i in range(6*7):
obj = tk.Label(self,relief="groove",width=2,height=1,font=("Arial",8,"bold"))
self.bulist.append( obj )
obj.grid(column=i%7,row=i/7)
obj.bind("<1>",self._auswahl)
obj.marked = False
obj.var = tk.StringVar()
obj.configure( textvariable = obj.var )
self.li = tk.Button(self, text = "<", relief = "groove",
bg = self.farben["bgbuttons"],
fg = self.farben["fgbuttons"],
command = self._zurueck)
self.re = tk.Button(self, text = ">", relief = "groove",
bg = self.farben["bgbuttons"],
fg = self.farben["fgbuttons"],
command = self._vor)
self.mi = tk.Label(self, text="2006/01",relief="groove",
bg = self.farben["bglabel"],
fg = self.farben["fglabel"])
self.li.grid(column=0,row=7)
self.re.grid(column=6,row=7)
self.mi.grid(column=1,row=7,columnspan=5,sticky="nsew")
self.set_monat(self.localtime()[1],self.localtime()[0])
def _color_set(self,objlist,farbname,forever=False):
BG = self.farben["bg"+farbname]
FG = self.farben["fg"+farbname]
for w in objlist:
w.configure(bg = BG, fg = FG)
if forever: w.last_color = (BG,FG)
def _color_reset(self,objlist):
for w in objlist:
w.configure( bg = w.last_color[0], fg = w.last_color[1] )
def _zurueck(self):
m, j = self.m-1, self.j
if m == 0: m = 12; j -= 1
self.set_monat(m, j)
def _vor(self):
m, j = self.m+1, self.j
if m == 13: m = 1; j += 1
self.set_monat(m, j)
def _markiere(self):
print "_markiere()"
if self.fkt1 == None: return
print " -> ok!"
li_tage1 = []
li_tage2 = []
li_tage3 = []
j2, m2 = self.j, self.m
j1, m1 = j2,m2-1
if m1 == -1: m1=11; j1-=1
j3, m3 = j2,m2+1
if m3 == 12: m3= 0; j3+=1
l1, l2, l3 = self.li_aufteilung1[:], self.li_aufteilung2[:], self.li_aufteilung3[:]
if len(l1)>1:
eins, zwei = l1[0], l1[-1]
for i in range(int(eins.var.get()),int(zwei.var.get())+1):
li_tage1.append(((j1,m1,i),l1[i-int( eins.var.get() )]) )
elif len(l1)==1:
li_tage1.append( ((j1, m1, int(l1[0].var.get())), l1[0]) )
eins, zwei = l2[0], l2[-1]
for i in range( int(eins.var.get()), int(zwei.var.get() ) +1):
li_tage2.append( ((j2, m2, i), l2[i-1]) )
eins, zwei = l3[0], l3[-1]
for i in range( int(eins.var.get()), int(zwei.var.get() ) +1):
li_tage3.append( ((j3, m3, i), l3[i-1]) )
l1 = self.fkt1( li_tage1 )
l2 = self.fkt1( li_tage2 )
l3 = self.fkt1( li_tage3 )
for liste,farbe in ((l1,"5"), (l2,"4"), (l3,"5")):
self._color_set(objlist = liste,
farbname= farbe,
forever = True)
for obj in liste:
obj.marked = True
def istSchaltjahr(self,jahr):
"1=istschaltjahr; 0=keinschaltjahr"
if (jahr%400==0)or(jahr%4==0 and jahr%100!=0):
return 1
else:
return 0
def anz_tage(self,monat,jahr):
"maximalanzahl der tage, die ein m haben kann (ohne schaltjahr!)"
if monat in (1,3,5,7,8,10,12):
return 31
elif monat in (4,6,9,11):
return 30
else:
return 28+self.istSchaltjahr(jahr)
def JACOBSTHAL(self,a):
"0=mo,1=di,...,6=so"
liD = [ i for i in range( self.anz_tage(self.m,self.j) + 1 ) ] # tag 1=1; tag 31=31
dict_k = {1:6+5*self.istSchaltjahr(self.j),
2:2+self.istSchaltjahr(self.j),
3:2,
4:5,5:0,
6:3,7:5,
8:1,9:4,
10:6,11:2,12:4}
k = dict_k[ self.m ]
c,j = divmod( self.j, 100 )
d = liD[a] + k + j + j/4 - 2*( c%4 )
wochentag = (d%7)-1
if wochentag == -1: wochentag = 6 # So
return wochentag
def set_monat(self,m,j=-1):
self.m = m
if j <> -1: self.j = j
self.mi.configure(text="%i/%0.2i"%(self.j,self.m))
startday = self.JACOBSTHAL(1) # der erste tag des aktuellen monats
endday = startday+self.anz_tage(self.m,self.j)-1
self.startday, self.endday = startday, endday # "globalisierung" fuer das event
premonth = self.m - 1; j1=self.j
if premonth == 0: premonth = 12; j1-=1
newmonth = self.m + 1; j2=self.j
if newmonth == 13: newmonth = 1; j2+=1
self.li_aufteilung1 = []
self.li_aufteilung2 = []
self.li_aufteilung3 = []
self.li_aufteilung4 = []
for i, obj in enumerate(self.bulist):
if i<startday: # alter monat
lab = (self.anz_tage(premonth,j1)-(startday-1)+i)
obj.var.set( "%0.2i" % lab)
self.li_aufteilung1.append(obj)
elif i>endday: # neuer monat
lab = (i-endday)
obj.var.set( "%0.2i" % lab)
self.li_aufteilung3.append(obj)
else: # aktueller monat
lab = ( i-(startday-1) )
obj.var.set( "%0.2i" % lab)
self.li_aufteilung2.append(obj)
if i%7 in (5,6): # wochenende
self.li_aufteilung4.append(obj)
obj.marked = False
# farbe:
self._color_set(self.li_aufteilung2,"2",forever=True)
self._color_set(self.li_aufteilung4,"weekend",forever=True)
self._color_set(self.li_aufteilung1,"1",forever=True)
self._color_set(self.li_aufteilung3,"3",forever=True)
self._color_set((self.li,self.re),"buttons",forever=False)
self._color_set((self.mi,),"label",forever=False)
self.configure(bg=self.farben["bglabel"])
self._markiere()
def _auswahl(self, event=None):
"wenn auf ein tag geklickt worden ist"
wid = event.widget
label = wid["text"]
# neusuche falls falscher monat
if wid in self.li_aufteilung1:
self._zurueck()
for w in self.li_aufteilung2:
if w["text"]==label:
wid = w; break
elif wid in self.li_aufteilung3:
self._vor()
for w in self.li_aufteilung2:
if w["text"]==label:
wid = w; break
# farbe setzen
self._color_set((wid,),"active")
# wurde doppelt geklickt?
if wid == self.last_choosen_widget:
return
# farbe des alten zuruecksetzen
if self.last_choosen_widget != -1:
self._color_reset( (self.last_choosen_widget,) )
# neues zum alten machen und auf neues warten
self.last_choosen_widget = wid
# datumstupel zB: (2006,05,21)
print self.get()
# externe funktion aufrufen.. die ZWEITE, die, die dann irgendwas macht...
if self.fkt2:
if wid.marked: self.fkt2(self.get())
def get(self):
"gibt aktuellen 'klick' aus zB: (2006,05,21)"
tu = (self.j,self.m,int(self.last_choosen_widget["text"]))
return tu
if __name__ == "__main__":
li = {(2006,06,03):"datum nr. eins",(2006,06,04):"datum nummer zwei",(2006,05,31):"drittes eingetragenes datum..."}
def externfkt1(doppeltupel):
objekte = []
global li
li_keys = li.keys()
for item,obj in doppeltupel:
if item in li_keys:
objekte.append(obj)
return objekte
def externfkt2(tripel):
global li
print li[tripel]
root = tk.Tk()
ka = KalFrame(root,fkt1 = externfkt1, fkt2 = externfkt2)
ka.pack()
root.mainloop()
die eine funktion liefert (zb. aus einer datei) die datumstupel und liefert die objekte, die eingefärbt werden müssen.
die andere funktion wird aufgerufen, wenn auf ein eingefärbtes (markiertes) widget geklickt wird.
(zb. um dann das dazugehörige event/ den termin in eine listbox einzugügen ...)
ich für meinen teil habe die klasse dann erben lassen damit man noch die farben einstellen kann, dass "multiwidget" irgendwo hineinlegen kann und damit man die funktionen besser zuordnen kann
- bitte noch keinen kommentar über die farben abgeben, die sind schon im fast vollendeten prog verbessert worden (und ich garantiere, dass sie besser aussehen, als das schrille grün
die sache, dass alles so schön untereinander / nebeneinander ist, ist absolut genial, da es einfach nur übersichtlich und gut aussehend ist *DAUMEN HOCH*
aber der kritikpunkt liegt trotzdem noch darin, dass man auf das weiße klicken kann und ein falsches datum ausgegeben wird...
und manchmal wird das fenster - bei mir jedenfalls - an der unterseite des bildschirmbereiches rausgekickt und man sieht so also nur die hälfte...