#!/usr/bin/python
# -*- coding: iso-8859-7 -*-
import codecs, bisect
from Tkinter import *
from p_ggen import thanUnicode,thanUnunicode,prg,path
from p_gtkuti import thanGudGetSaveFile,thanGudGetReadFile,thanGudGetDir,\
ThanDialog
from thanwidstrans import T
##############################################################################
##############################################################################
class ThanMenu(Menu):
"""A menu that shows status when a user interacts with it.
If function condition is set, this function is checked before
a menu action. If condition() returns False, no action is taken.
The keyword "help" provides the status text for each menu entry.
A character which is prepended by &, is underlined.
"""
def __init__(self, master, *args, **kw):
try: self.__condition = master.__condition
except: self.__condition = None
if "condition" in kw: self.__condition = kw.pop("condition")
try: self.__stat = master.__stat
except: self.__stat = None
if "statcommand" in kw: self.__stat = kw.pop("statcommand")
kw["tearoff"] = False
Menu.__init__(self, master, *args, **kw)
if self.__stat != None:
self.bind("<Motion>", self.__onmotion)
self.bind("<Leave>", lambda evt, s=self.__stat: s(""))
self.__ypos = None
self.__statText = []
def __onmotion(self, evt):
if self.__ypos == None:
yp = [self.yposition(0)]
if yp[0] == 0: return
for i in xrange(1, 100):
yp1 = self.yposition(i)
if yp1 == yp[-1]: break
yp.append(yp1)
self.__ypos = yp
i = bisect.bisect_left(self.__ypos, evt.y) - 1
self.__stat(self.__statText[i])
def add(self, itemType, cnf=None, **kw):
if cnf == None: cnf = {}
i = self.index(END)
if i == None: i = -1
assert i == len(self.__statText)-1, "Index missing in ThanMenu!!"
cnf.update(kw)
self.__statText.append(cnf.pop("help", ""))
cnf = self.__entryparse(cnf)
Menu.add(self, itemType, cnf)
def insert(self, index, itemType, cnf=None, **kw):
if cnf == None: cnf = {}
i = index - 1
assert i < len(self.__statText), "Index missing in ThanMenu!!"
cnf.update(kw)
self.__statText.insert(i, cnf.pop("help", ""))
Menu.insert(self, index, itemType, self.__entryparse(cnf))
def delete(self, index1, index2=None):
i1 = index1
if index2 == None: i2 = i1 + 1
elif index2 == END: i2 = len(self.__statText)
else: i2 = index2+1 # Tkinter deletes index1:index2 (INCLUDING index2)
del self.__statText[i1:i2]
self.__ypos = None
Menu.delete(self, index1, index2)
def entryconfig(self, index, **kw):
if "help" in kw: self.__statText[index-1] = kw.pop("help")
Menu.entryconfig(self, index, **self.__entryparse(kw))
def __entryparse(self, kw):
try:
lab = kw["label"]
i = lab.find("&")
if 0 <= i < len(lab)-1:
kw["label"] = lab.replace("&", "", 1)
kw.setdefault("underline", i)
except KeyError: pass
if self.__condition == None or "command" not in kw: return kw
kw["command"] = lambda evt, c=kw["command"]: self.__checkCommand(evt, c)
return kw
def __checkCommand(self, evt, fun):
if self.__condition(): fun(evt)
def destroy(self):
self.__stat = self.__condition = None #2008_09_12: Python 2.6rc1 calls destroy and..
self.unbind("<Motion>") #.. then entryconfig whgich accesses __condition!!
self.unbind("<Leave>")
self.delete(0, END)
Menu.destroy(self)
def __del__(self): print "ThanMenu", self, "is deleted"
##############################################################################
##############################################################################
class ThanListbox(Listbox):
"A standard listbox with unicode capabilities."
def __init__(self, *args, **kw):
"Save selection mode."
self.__selectionmode = kw.get("selectmode", SINGLE)
Listbox.__init__(self, *args, **kw)
def thanGet(self, *args):
"Transform to string and then get."
a = self.get(*args)
try: a+"s"
except: return [thanUnunicode(x) for x in a]
else: return thanUnunicode(a)
def thanInsert(self, i, items):
"Transform to unicode and then insert."
try: items+"s"
except: self.insert(i, [thanUnicode(x) for x in items])
else: self.insert(i, thanUnicode(items))
def thanSet(self, items):
"Empty list and set new values to the listbox."
self.delete(0, END)
self.thanInsert(0, items)
def thanAppend(self, items):
"Append new values to the end of the listbox."
self.thanInsert(END, items)
def thanGetSelection(self):
"Gets the chosen value and returns it."
indexes = self.curselection()
if len(indexes) < 1: result = [self.thanGet(ACTIVE)]
else: result = [self.thanGet(int(i)) for i in indexes]
if self.__selectmode == SINGLE: return result[0]
else: return result
##############################################################################
##############################################################################
class ThanChoice(Menubutton):
"A widget that lets the user choose one of predetermined choices."
def __init__(self, master, **kw):
Menubutton.__init__(self, master)
self.thanMenu = Menu(self, tearoff=0)
kw.setdefault("labels", ("",))
kw.setdefault("command", lambda i, lab: None)
kw.setdefault("width", 10)
self.thanChoice = 0
self.config(**kw)
def config(self, **kw):
"Adds labels and command support to standard config, and propagates some attributes to menu."
try: self.thanCommand = kw["command"]
except KeyError: pass
else: del kw["command"]
try: self.thanLabels = tuple(kw["labels"])
except KeyError: pass
else:
del kw["labels"]
m = Menu(self, tearoff=0)
self["menu"] = m
self.thanMenu.destroy()
self.thanMenu = m
for i,key in enumerate(self.thanLabels):
m.add_command(label=thanUnicode(key), command=lambda i=i: self.__set(i))
self.thanSet(0)
Menubutton.config(self, **kw)
self.thanMenu.config(**rdict(kw, "font", "class_"))
def thanSet(self, i):
self.thanChoice = i
Menubutton.config(self, text=thanUnicode(self.thanLabels[i]))
def thanSetText(self, t):
for i,key in enumerate(self.thanLabels):
if key == t: break
else: raise IndexError, t
self.thanChoice = i
Menubutton.config(self, text=thanUnicode(key))
def __set(self, i):
self.thanChoice = i
Menubutton.config(self, text=thanUnicode(self.thanLabels[i]))
self.thanCommand(i, self.thanLabels[i])
def thanGet(self): return self.thanChoice
def thanGetText(self): return self.thanLabels[self.thanChoice]
def destroy(self):
# print "ThanChoice", self, "destroy called"
self.thanMenu.destroy()
del self.thanMenu, self.thanCommand, self.thanChoice
Menubutton.destroy(self)
def __del__(self): print "ThanChoice", self, "is deleted"
##############################################################################
##############################################################################
class ThanPoplist(ThanDialog):
"Displays a popup window with a list of choices; cancel/ok buttons are not required."
def __init__(self, master, val, width=20, height=10, selectmode=SINGLE, *args, **kw):
"Extract initial draw order."
self.__val = val
self.__opts = dict(width=width, height=height)
self.__selectmode = selectmode
# self.result = None
ThanDialog.__init__(self, master, *args, **kw)
def body(self, fra):
"Create dialog widgets."
self.__listForm(fra, 0, 0)
self.__filist()
return self.__li # This widget has the focus
def __listForm(self, fra, ir, ic):
"Creates and shows list."
fra.columnconfigure(0, weight=1)
fra.rowconfigure(0, weight=1)
self.__li = Listbox(fra, selectmode=self.__selectmode, exportselection=0)
self.__li.grid(row=ir, column=ic, sticky="wesn")
sc = Scrollbar(fra, orient=VERTICAL, command=self.__li.yview)
# Change the color of inactive indicator to the color of active indicator
# because it was confusing to change color when you pressed the button
sc.config(background=sc["activebackground"])
sc.grid(row=ir, column=ic+1, sticky="sn")
self.__li.config(yscrollcommand=sc.set)
self.__li.bind("<Button-1>", lambda evt: self.__li.after(100, self.__onListClick))
def __filist(self):
"Fills the list with the user supplied values."
self.__opts["height"] = min(self.__opts["height"], len(self.__val))
self.__li.config(**self.__opts)
for val in self.__val:
self.__li.insert(END, thanUnicode(val))
del self.__opts
def buttonbox(self):
"Do not display the default buttons in single mode."
if self.__selectmode == SINGLE:
self.bind("<Return>", self.__onListClick)
self.bind("<Escape>", self.cancel)
else:
ThanDialog.buttonbox(self)
# def __onListClickOld(self, evt=None):
# "Gets the chosen valure and returns it."
# indexes = self.__li.curselection()
# if len(indexes) < 1: i = ACTIVE
# else: i = int(indexes[0])
# self.result = self.__li.get(i)
# self.ok()
def __onListClick(self, evt=None):
"Gets the chosen valure and returns it."
if self.__selectmode == SINGLE: self.ok()
def apply(self):
"Gets the chosen value and returns it."
indexes = self.__li.curselection()
print "ThanPopList: ACTIVE=", ACTIVE, "type=", type(ACTIVE)
if len(indexes) < 1: self.result = [self.__val[self.__li.index(ACTIVE)]]
else: self.result = [self.__val[int(i)] for i in indexes]
if self.__selectmode == SINGLE: self.result = self.result[0]
del self.__val
def destroy(self):
"Deletes references to widgets, so that it breaks circular references."
del self.__li
ThanDialog.destroy(self)
def __del__(self):
print "ThanPoplist ThanDialog", self, "dies.."
def testPoplist():
root = Tk()
win = ThanPoplist(root, (20*"thanasis dimitra andreas stella").split(), width=30, height=50, title="Choose someone")
print win.result
def testPoplistextented():
root = Tk()
win = ThanPoplist(root, (20*"thanasis dimitra andreas stella").split(), width=30, height=50, selectmode=EXTENDED, title="Choose someone")
print win.result
##############################################################################
##############################################################################
class ThanPoplistCol(ThanDialog):
"Displays a popup window with a list of choices; cancel/ok buttons are not required."
def __init__(self, master, val, width=20, height=10, selectmode=SINGLE, *args, **kw):
"Extract initial draw order."
self.__val = val
self.__opts = dict(width=width, height=height)
self.__selectmode = selectmode
# self.result = None
ThanDialog.__init__(self, master, *args, **kw)
def body(self, fra):
"Create dialog widgets."
self.__listForm(fra, 0, 0)
self.__filist()
return self.__li # This widget has the focus
def __listForm(self, fra, ir, ic):
"Creates and shows list."
fra.columnconfigure(0, weight=1)
fra.rowconfigure(0, weight=1)
self.__li = ThanScrolledText(fra)
self.__li.grid(row=ir, column=ic, sticky="wesn")
def __filist(self):
"Fills the list with the user supplied values."
import p_gimdxf
self.__opts["height"] = min(self.__opts["height"], len(self.__val))
self.__opts.setdefault("cursor", "arrow")
self.__li.config(**self.__opts)
for name, col in self.__val:
tag = "t%03d%03d%03d" % col
if p_gimdxf.thanRgb2Gray(col) < 127: fg = "white"
else: fg = "black"
bg = p_gimdxf.thanFormTkcol % col
self.__li.tag_config(tag, foreground=fg, background=bg)
self.__li.tag_bind(tag, "<1>", lambda evt, name=name: self.__onclick(evt, name))
self.__li.thanAppend(thanUnicode(name)+"\n", tag)
del self.__opts
def __filist2(self):
"Fills the list with the user supplied values."
import p_gimdxf
self.__opts["height"] = min(self.__opts["height"], 2*len(self.__val))
self.__opts.setdefault("cursor", "arrow")
self.__li.config(**self.__opts)
tt = self.__li.thanText
for name, col in self.__val:
tag = "t%03d%03d%03d" % col
if p_gimdxf.thanRgb2Gray(col) < 127: fg = "white"
else: fg = "black"
bg = p_gimdxf.thanFormTkcol % col
but = ThanButton(tt, width=20, height=1, anchor="e", text=name, foreground=fg, background=bg,
activebackground="green", command=lambda name=name: self.__onclick(name))
tt.window_create(END, window=but, align=BASELINE)
del self.__opts
def buttonbox(self):
"Do not display the default buttons in single mode."
if self.__selectmode == SINGLE:
self.bind("<Return>", self.__onListClick)
self.bind("<Escape>", self.cancel)
else:
ThanDialog.buttonbox(self)
# def __onListClickOld(self, evt=None):
# "Gets the chosen valure and returns it."
# indexes = self.__li.curselection()
# if len(indexes) < 1: i = ACTIVE
# else: i = int(indexes[0])
# self.result = self.__li.get(i)
# self.ok()
def __onclick(self, evt, name):
"The user chose something."
prg("ThanPoplistCol: user clicked: %s" % name)
def __onListClick(self, evt=None):
"Gets the chosen valure and returns it."
if self.__selectmode == SINGLE: self.ok()
def apply(self):
"Gets the chosen value and returns it."
indexes = self.__li.curselection()
print "ThanPopList: ACTIVE=", ACTIVE, "type=", type(ACTIVE)
if len(indexes) < 1: self.result = [self.__val[self.__li.index(ACTIVE)]]
else: self.result = [self.__val[int(i)] for i in indexes]
if self.__selectmode == SINGLE: self.result = self.result[0]
del self.__val
def destroy(self):
"Deletes references to widgets, so that it breaks circular references."
del self.__li
ThanDialog.destroy(self)
def __del__(self):
print "ThanPoplist ThanDialog", self, "dies.."
def testPoplist():
root = Tk()
win = ThanPoplist(root, (20*"thanasis dimitra andreas stella").split(), width=30, height=50, title="Choose someone")
print win.result
def testPoplistextented():
root = Tk()
win = ThanPoplist(root, (20*"thanasis dimitra andreas stella").split(), width=30, height=50, selectmode=EXTENDED, title="Choose someone")
print win.result
##############################################################################
##############################################################################
class ThanYesno(ThanChoice):
"Choice of yes or no."
def __init__(self, master, **kw):
kw["labels"] = T["Yes"], T["No"]
kw.setdefault("width", 3)
ThanChoice.__init__(self, master, **kw)
def thanSet(self, i):
if i: ThanChoice.thanSet(self, 0)
else: ThanChoice.thanSet(self, 1)
def thanGet(self):
if self.thanChoice == 0: return 1
else: return 0
class ThanCheck(Checkbutton):
"A Tkinter Checkbutton with ThanSet/ThanGet support."
def __init__(self, *args, **kw):
"Automatically create control variable."
self.thanVar = IntVar()
assert "variable" not in kw, "ThanCheck automatically creates private control variable!"
kw["variable"] = self.thanVar
Checkbutton.__init__(self, *args, **kw)
def thanSet(self, val):
"Set the value as bool."
self.thanVar.set(bool(val))
def thanGet(self):
"Get the value as bool."
return bool(self.thanVar.get())
def destroy(self):
"Make sure that all new class variable are deleted."
del self.thanVar
Checkbutton.destroy(self)
class ThanRadio(Frame):
"A Tkinter Radiobutton with ThanSet/ThanGet support."
def __init__(self, *args, **kw):
"Automatically create control variable."
self.thanVar = IntVar()
self.ival = 0
self.thanChildren = []
Frame.__init__(self, *args, **kw)
def add_button(self, *args, **kw):
assert "variable" not in kw, "ThanRadio automatically creates private control variable!"
kw["variable"] = self.thanVar
kw["value"] = self.ival
self.ival += 1
rad = Radiobutton(self, *args, **kw)
self.thanChildren.append(rad)
return rad
def config(self, *args, **kw):
"Propagate to children."
for rad in self.thanChildren:
rad.config(*args, **kw)
def thanSet(self, val):
"Set the value as integer."
self.thanVar.set(int(val))
def thanGet(self):
"Get the value as integer."
return int(self.thanVar.get())
def destroy(self):
"Make sure that all new class variable are deleted."
del self.thanChildren, self.thanVar
Frame.destroy(self)
##############################################################################
##############################################################################
class ThanCombo(Frame):
"A widget that lets the user choose one of predetermined choices or write a text."
def __init__(self, master, **kw):
Frame.__init__(self, master)
self.thanText = ThanEntry(self)
self.thanText.grid(row=0, column=0, sticky="ew")
self.thanMenubutton = Menubutton(self, text="...", padx=0, pady=0)
self.thanMenubutton.grid(row=0, column=1, sticky="w")
self.thanMenu = Menu(self.thanMenubutton, tearoff=0)
kw.setdefault("labels", ("",))
kw.setdefault("command", lambda i, lab: None)
kw.setdefault("width", 10)
self.config(**kw)
self.columnconfigure(0, weight=1)
def config(self, **kw):
"Adds labels and command support to standard config, and propagates some attributes to menu."
try: self.thanCommand = kw["command"]
except KeyError: pass
else: del kw["command"]
try: self.thanLabels = tuple(kw["labels"])
except KeyError: pass
else:
del kw["labels"]
m = Menu(self.thanMenubutton, tearoff=0)
self.thanMenubutton["menu"] = m
self.thanMenu.destroy()
self.thanMenu = m
for i,key in enumerate(self.thanLabels):
m.add_command(label=thanUnicode(key), command=lambda i=i: self.__comboSet(i))
self.__comboSet(0)
if "relief" in kw: kw.setdefault("borderwidth", 1)
Frame.config(self, **rdict(kw, "relief", "borderwidth", "class_"))
self.thanText.config( **rdict(kw, "state", "font", "width", "class_"))
self.thanMenubutton.config(**rdict(kw, "state", "font", "class_", "bg", "background"))
self.thanMenu.config( **rdict(kw, "font", "class_"))
def __comboSet(self, i):
self.thanChoice = i
self.thanSet(self.thanLabels[i])
self.thanCommand(i, self.thanLabels[i])
def thanSet(self, t): self.thanText.thanSet(t)
def thanGet(self): return self.thanText.get()
def destroy(self):
# print "ThanCombo", self, "destroy called"
del self.thanMenu, self.thanMenubutton, self.thanText
Frame.destroy(self)
def __del__(self): print "ThanCombo", self, "is deleted"
##############################################################################
##############################################################################
class ThanFile(Frame):
"A widget which lets the user choose a file."
def __init__(self, master, text="", extension=".txt", mode="r", initialdir="", title="Open file", **kw):
Frame.__init__(self, master)
self.initialdir = initialdir
self.thanText = ThanEntry(self, justify="right")
self.thanText.grid(row=0, column=0, sticky="ew")
self.thanMenubutton = Button(self, text="...", relief=FLAT, padx=0, pady=0,
bg="lightcyan", activebackground="cyan", command=self.__open)
self.thanMenubutton.grid(row=0, column=1, sticky="w")
self.thanExt, self.thanMode, self.thanTitle = extension, mode, title
self.thanCommand = lambda filnam : True
self.thanSet(text)
kw.setdefault("width", 10)
self.config(**kw)
self.columnconfigure(0, weight=1)
def __open(self):
filnam = self.thanText.thanGet()
if self.thanMode == "r":
filnam = thanGudGetReadFile(self, self.thanExt, self.thanTitle,
initialdir=self.initialdir, initialfile=filnam)
elif self.thanMode == "w":
filnam = thanGudGetSaveFile(self, self.thanExt, self.thanTitle,
initialdir=self.initialdir, initialfile=filnam)
else:
filnam = thanGudGetDir(self, self.thanTitle, initialdir=self.initialdir)
if filnam == None: return
if self.thanCommand(filnam): # Let user do something
self.thanSet(filnam)
self.initialdir = path(filnam).abspath().parent
def config(self, **kw):
"Adds labels and command support to standard config, and propagates some attributes to menu."
try: self.thanExt = kw.pop("extension")
except KeyError: pass
try: self.thanCommand = kw.pop("command")
except KeyError: pass
if "relief" in kw: kw.setdefault("borderwidth", 1)
Frame.config(self, **rdict(kw, "relief", "borderwidth", "class_"))
self.thanText.config( **rdict(kw, "state", "font", "width", "class_"))
self.thanMenubutton.config(**rdict(kw, "state", "font", "class_"))
def thanSet(self, t): self.thanText.thanSet(t)
def thanGet(self): return self.thanText.thanGet()
def invoke(self): self.thanMenubutton.invoke()
def focus_set(self): self.thanText.focus_set()
def destroy(self):
# print "ThanFile", self, "destroy called"
del self.thanMenubutton, self.thanText
Frame.destroy(self)
def __del__(self): print "ThanFile", self, "is deleted"
##############################################################################
##############################################################################
class ThanText(Text):
"A standard text which copes with greek text and windows/linux iconsistencies."
_SENTINEL = 2000000000
def __init__(self, master, **kw):
"Handle resize capability."
self.__idResize = None
self.__maxLines = self._SENTINEL
Text.__init__(self, master)
self.config(**kw)
def config(self, **kw):
"Just get maxlines attribute."
n = kw.pop("maxlines", None)
Text.config(self, **kw)
if n == None: return
if n <= 0: n = self._SENTINEL # Resize is going to be cancelled
self.__maxLines = n
self.__resize() # Force resize now
def thanIndex(self, index1):
"Return the line.column index corresponding to the given index as two integers."
t = str(self.index(index1)).split(".")
return int(t[0]), int(t[1])
def set_insert(self, index):
"Sets the insertion cursor at index simulating mouse click."
self.update()
b = self.bbox(index)
if b == None:
self.see(index)
self.update()
b = self.bbox(index)
if b == None:
print "ThanText.set_insert() failed. No position has been set."
return
self.event_generate("<Button-1>", x=b[0], y=b[1])
self.event_generate("<ButtonRelease-1>", x=b[0], y=b[1])
def thanSet(self, t, tags=()):
self.delete(1.0, END)
t = thanUnicode(t)
self.insert(1.0, t, tags)
def thanInsert(self, ipos, t, tags=()):
"Inserts text at position."
t = thanUnicode(t)
Text.insert(self, ipos, t, tags)
def thanAppend(self, t, tags=()):
t = thanUnicode(t)
self.insert(END, t, tags)
self.set_insert(END+"-1c")
def thanGet(self):
"Get all content of widget."
t = self.get(1.0, END)[:-1]
return thanUnunicode(t)
def thanGetPart(self, ipos1, ipos2):
"Get partial content of widget."
t = self.get(ipos1, ipos2)
return thanUnunicode(t)
def __resize(self):
"Keep total number of lines less than __maxLines."
if self.__maxLines >= self._SENTINEL: return # Avoid race conditions
if self.__idResize != None: self.after_cancel(self.__idResize) # In case thanResize was explicitely called
n = self.get("1.0", END).count("\n")
n = n - self.__maxLines + 1
if n > 0: self.delete("1.0", "%d.0" % n)
self.__idResize = self.after(60000, self.__resize)
def __del__(self): print "ThanText", self, "is deleted"
##############################################################################
##############################################################################
class ThanScrolledText(Frame):
"""Modified standard ScrolledText provided py python distribution.
A horizontal scrollbar is implemented.
Keywords vbar,hbar control the placement of vertical and horizontal bars.
Default vbar=1, hbar=0.
It uses the grid geometry manager.
It changes the colour of the vertical scroll bar.
Function apply was converted to a more readable form.
"""
def set_insert (self, *args, **kw): return self.thanText.set_insert (*args, **kw)
def thanSet (self, *args, **kw): return self.thanText.thanSet (*args, **kw)
def thanInsert (self, *args, **kw): return self.thanText.thanInsert (*args, **kw)
def thanAppend (self, *args, **kw): return self.thanText.thanAppend (*args, **kw)
def thanGet (self, *args, **kw): return self.thanText.thanGet (*args, **kw)
def thanGetPart(self, *args, **kw): return self.thanText.thanGetPart(*args, **kw)
def tag_config (self, *args, **kw): return self.thanText.tag_config (*args, **kw)
def tag_bind (self, *args, **kw): return self.thanText.tag_bind (*args, **kw)
def bindte (self, *args, **kw): return self.thanText.bind (*args, **kw)
def index (self, *args, **kw): return self.thanText.index (*args, **kw)
def thanIndex (self, *args, **kw): return self.thanText.thanIndex (*args, **kw)
def focus_sette(self, *args, **kw): return self.thanText.focus_set (*args, **kw)
def __init__(self, master=None, **kw):
Frame.__init__(self, master)
drawHbar = kw.pop("hbar", 0)
drawVbar = kw.pop("vbar", 1)
self.vbar = self.hbar = None
if drawVbar:
self.vbar = Scrollbar(self, name='vbar')
# Change the color of inactive indicator to the color of active indicator
# because it was confusing to change color when you pressed the button
self.vbar.config(background=self.vbar["activebackground"])
self.vbar.grid(row=0, column=1, sticky="sn")
if drawHbar:
self.hbar = Scrollbar(self, name='hbar', orient=HORIZONTAL)
self.hbar.config(background=self.hbar["activebackground"])
self.hbar.grid(row=1, column=0, sticky="we")
self.thanText = ThanText(self)
self.thanText.grid(row=0, column=0, sticky="wesn")
if drawVbar:
self.thanText['yscrollcommand'] = self.vbar.set
self.vbar['command'] = self.thanText.yview
if drawHbar:
self.thanText['xscrollcommand'] = self.hbar.set
self.hbar['command'] = self.thanText.xview
self.config(**kw)
self.rowconfigure(0, weight=1)
self.columnconfigure(0, weight=1)
# if drawVbar: self.columnconfigure(0, weight=1)
# if drawHbar: self.rowconfigure(1, weight=1)
def config(self, **kw):
"Propagates attributes to the correct widgwet."
if "relief" in kw: kw.setdefault("borderwidth", 1)
kwf = {}
for a in "relief bd borderwidth".split():
if a in kw: kwf[a] = kw.pop(a)
for a in "class_ ".split():
if a in kw: kwf[a] = kw[a]
Frame.config(self, **kwf)
self.thanText.config(**kw)
def destroy(self):
"Delete/destroy any variables we created and saved a reference."
del self.vbar, self.hbar, self.thanText
Frame.destroy(self) # This will call thanText.destroy()
def __del__(self):
print "ThanScrolledText", self, "dies.."
##############################################################################
##############################################################################
class ThanEntry(Entry):
"A standard entry which changes color if it is disabled."
def __init__(self, master, **kw):
Entry.__init__(self, master, **kw)
self.__normalforeground = self["foreground"]
self.__disabledforeground = _disfg(master)
def config(self, **kw):
"Changes color when disabled."
if "state" in kw:
if kw["state"] == NORMAL:
kw.setdefault("foreground", self.__normalforeground)
self.__normalforeground = kw["foreground"]
else:
kw.setdefault("foreground", self.__disabledforeground)
self.__disabledforeground = kw["foreground"]
Entry.config(self, **kw)
def thanSet(self, t):
self.delete(0, END)
self.insert(0, thanUnicode(t))
def thanGet(self): return thanUnunicode(self.get())
def __del__(self): print "ThanEntry", self, "is deleted"
##############################################################################
##############################################################################
class ThanLabel(Label):
"A standard label with thanSet, thanGet and unicode capabilities."
def __init__(self, master, **kw):
kw.setdefault("relief", GROOVE)
kw.setdefault("bd", 3)
kw.setdefault("anchor", W)
kw.setdefault("width", 10)
Label.__init__(self, master, **kw)
def thanSet(self, t):
self.config(text=thanUnicode(t))
self.update_idletasks()
def thanGet(self): return thanUnunicode(self.cget("text"))
def __del__(self): print "ThanLabel", self, "is deleted"
##############################################################################
##############################################################################
class ThanButton(Button):
"A standard label with thanSet, thanGet and unicode capabilities."
def __init__(self, *args, **kw):
"Make unicode text."
text = kw.pop("text", None)
Button.__init__(self, *args, **kw)
if text != None: self.thanSet(text)
def thanSet(self, t):
"Set the text of the button and convert to unicode."
self.config(text=thanUnicode(t))
self.update_idletasks()
def thanGet(self):
"Get the text of the button and convert to string."
return thanUnunicode(self.cget("text"))
def __del__(self): print "ThanButton", self, "is deleted"
##############################################################################
##############################################################################
class ThanToolButton(Button):
"Button to be used in toolbar and show help on button."
def __init__(self, *args, **kw):
if "help" not in kw: return Button.__init__(self, *args, **kw)
self.__help = kw.pop("help")
Button.__init__(self, *args, **kw)
self.__cron = None
self.__helpWin = w = Toplevel(self)
w.overrideredirect(True)
lab = Label(w, text=self.__help, bg="lightyellow")
lab.grid()
self.bind("<Enter>", self.__cronHelpWin)
self.bind("<Leave>", self.__unCronHelpWin)
w.bind("<ButtonPress>", self.__unCronHelpWin) # In case of bug we should be able to delete it
w.withdraw()
def __cronHelpWin(self, *args):
if self.__cron == None:
self.__cron = self.after(1000, self.__helpWinShow)
def __unCronHelpWin(self, *args):
if self.__cron != None:
self.after_cancel(self.__cron)
self.__cron = None
self.__helpWin.withdraw()
def __helpWinShow(self):
self.__cron = None
w = self.__helpWin
self.update()
x = self.winfo_rootx()
y = self.winfo_rooty() + self.winfo_height() + 1
w.geometry("%+d%+d" % (x, y))
w.deiconify()
def destroy(self):
# print "ThanToolButton", self, "destroy called"
self.__unCronHelpWin()
del self.__helpWin
Button.destroy(self)
def __del__(self): print "ThanToolButton", self, "is deleted"
##############################################################################
##############################################################################
def rdict(kw, *allowed):
"Returns an reduced dictionary which contains only the keys *allowed."
kw1 = {}
for key in allowed:
try: kw1[key] = kw[key]
except KeyError: pass
return kw1
thanDisabledforeground = None
def _disfg(master):
global thanDisabledforeground
if thanDisabledforeground == None:
dummy = Button(master)
thanDisabledforeground = dummy["disabledforeground"]
dummy.destroy()
return thanDisabledforeground
##############################################################################
##############################################################################
def dddd():
global mb1
mb1.destroy()
del mb1
if __name__ == "__main__":
def testpop(evt=None):
# win = ThanPoplist(mb31, (20*" dimitra andreas stella").split(), width=30, height=50, title="Choose someone")
win = ThanPoplistCol(mb31, 2*(("", (255,0,0)),
("dimitra", (0,255,0)),
("andreas", (0,0,255)),
("stella", (255,255,0)),
), width=30, height=50, title="Choose someone")
print "ThanPoplist result =", win.result
def testpopext(evt=None):
win = ThanPoplist(mb31, (20*"thanasis dimitra stella").split(), width=30, height=50, selectmode=EXTENDED, title="Choose someone")
print "ThanPoplist result =", win.result
def pr(a): print a
root = Tk()
if sys.platform == "win32":
root.option_add("*font", "Arial 10")
else:
import tkFont
f=tkFont.Font(family="Thorndale AMT", size=12)
# f=tkFont.Font(family="monospace", size=12)
root.option_add("*font", f)
mb1 = ThanMenu(root)
m = ThanMenu(mb1, tearoff=False, statcommand=pr)
m.add_command(label="a", help="Well.. a")
m.add_command(label="b", help="Well.. b")
mb1.add_cascade(label="ab", menu=m)
root["menu"] = mb1
del m
labs = ("Thanasis", "", "Andreas")*10
print labs
mb2 = ThanChoice(root, labels=labs, relief=RAISED)
mb2.grid()
mb3 = ThanYesno(root, relief=RAISED)
mb3.grid()
mb31 = Button(root, text="Try ThanPoplist", command=testpop)
mb31.grid()
mb32 = Button(root, text="Try ThanPoplist Extended", command=testpopext)
mb32.grid()
mb4 = ThanCombo(root, labels=("Thanasis", "Dimitra", "Andreas"), relief=RAISED)
mb4.grid()
mb5 = ThanFile(root, "no file", ".gan", "r", "Define gan file", relief=RAISED)
mb5.grid()
mb6 = ThanFile(root, "no dir", "", "d", "Define dir file", relief=RAISED)
mb6.grid()
mb7 = ThanText(root, width=20, height=8, maxlines=4)
mb7.grid()
mb8 = ThanEntry(root)
mb8.grid()
mb8.thanSet("This should be disabled")
mb8.config(state=DISABLED)
mb9 = ThanToolButton(root, text="Press", help="Show the working of ThanToolButton", command=dddd)
mb9.grid()
mb10 = ThanRadio(root)
mb10.grid()
rad = mb10.add_button(text="AA")
rad.grid(row=0, column=0)
rad = mb10.add_button(text="BB")
rad.grid(row=0, column=1)
rad = mb10.add_button(text="CC")
rad.grid(row=1, column=0)
rad = mb10.add_button(text="DD")
rad.grid(row=1, column=1)
root.mainloop()
|