曾与蒿藜同雨露,한때 잡초와 쑥과 함께 비와 이슬을 나누던 곳이 이제는 소나무와 삼나무와 함께 서리와 눈을 견뎌내고 있다.终随松柏到冰霜.かつては雑草やヨモギと共に雨や露を分かち合っていたが、今では松やヒノキと共に霜や雪に耐えている。曾与蒿藜同雨露,Once sharing rain and dew with weeds and wormwood, now enduring frost and snow with pines and cypresses.终随松柏到冰霜.曾与蒿藜同雨露한때 잡초와 쑥과 함께 비와 이슬을 나누던 곳이 이제는 소나무와 삼나무와 함께 서리와 눈을 견뎌내고 있다.,终随松柏到冰霜.譖セ荳手珍阯懷酔髮ィ髴イ�檎サ磯囂譚セ譟丞芦蜀ー髴�曾与蒿藜同雨露,鏇句笌钂胯棞鍚岄洦闇诧紝缁堥殢鏉炬煆鍒板啺闇�终随松柏到冰霜.曾与蒿藜同雨露,한때 잡초와 쑥과 함께 비와 이슬을 나누던 곳이 이제는 소나무와 삼나무와 함께 서리와 눈을 견뎌내고 있다.终随松柏到冰霜.曾与蒿藜同雨露,终随松柏到冰霜.
# The options of a widget are described by the following attributes
# of the Pack and Widget dialogs:
#
# Dialog.current: {name: value}
# -- changes during Widget's lifetime
#
# Dialog.options: {name: (default, klass)}
# -- depends on widget class only
#
# Dialog.classes: {klass: (v0, v1, v2, ...) | 'boolean' | 'other'}
# -- totally static, though different between PackDialog and WidgetDialog
# (but even that could be unified)
from Tkinter import *
class Option:
varclass = StringVar # May be overridden
def __init__(self, dialog, option):
self.dialog = dialog
self.option = option
self.master = dialog.top
self.default, self.klass = dialog.options[option]
self.var = self.varclass(self.master)
self.frame = Frame(self.master)
self.frame.pack(fill=X)
self.label = Label(self.frame, text=(option + ":"))
self.label.pack(side=LEFT)
self.update()
self.addoption()
def refresh(self):
self.dialog.refresh()
self.update()
def update(self):
try:
self.current = self.dialog.current[self.option]
except KeyError:
self.current = self.default
self.var.set(self.current)
def set(self, e=None): # Should be overridden
pass
class BooleanOption(Option):
varclass = BooleanVar
def addoption(self):
self.button = Checkbutton(self.frame,
text='on/off',
onvalue=1,
offvalue=0,
variable=self.var,
relief=RAISED,
borderwidth=2,
command=self.set)
self.button.pack(side=RIGHT)
class EnumOption(Option):
def addoption(self):
self.button = Menubutton(self.frame,
textvariable=self.var,
relief=RAISED, borderwidth=2)
self.button.pack(side=RIGHT)
self.menu = Menu(self.button)
self.button['menu'] = self.menu
for v in self.dialog.classes[self.klass]:
self.menu.add_radiobutton(
label=v,
variable=self.var,
value=v,
command=self.set)
class StringOption(Option):
def addoption(self):
self.entry = Entry(self.frame,
textvariable=self.var,
width=10,
relief=SUNKEN,
borderwidth=2)
self.entry.pack(side=RIGHT, fill=X, expand=1)
self.entry.bind('<Return>', self.set)
class ReadonlyOption(Option):
def addoption(self):
self.label = Label(self.frame, textvariable=self.var,
anchor=E)
self.label.pack(side=RIGHT)
class Dialog:
def __init__(self, master):
self.master = master
self.fixclasses()
self.refresh()
self.top = Toplevel(self.master)
self.top.title(self.__class__.__name__)
self.top.minsize(1, 1)
self.addchoices()
def refresh(self): pass # Must override
def fixclasses(self): pass # May override
def addchoices(self):
self.choices = {}
list = []
for k, dc in self.options.items():
list.append((k, dc))
list.sort()
for k, (d, c) in list:
try:
cl = self.classes[c]
except KeyError:
cl = 'unknown'
if type(cl) == TupleType:
cl = self.enumoption
elif cl == 'boolean':
cl = self.booleanoption
elif cl == 'readonly':
cl = self.readonlyoption
else:
cl = self.stringoption
self.choices[k] = cl(self, k)
# Must override:
options = {}
classes = {}
# May override:
booleanoption = BooleanOption
stringoption = StringOption
enumoption = EnumOption
readonlyoption = ReadonlyOption
class PackDialog(Dialog):
def __init__(self, widget):
self.widget = widget
Dialog.__init__(self, widget)
def refresh(self):
self.current = self.widget.info()
self.current['.class'] = self.widget.winfo_class()
self.current['.name'] = self.widget._w
class packoption: # Mix-in class
def set(self, e=None):
self.current = self.var.get()
try:
apply(self.dialog.widget.pack, (),
{self.option: self.current})
except TclError, msg:
print msg
self.refresh()
class booleanoption(packoption, BooleanOption): pass
class enumoption(packoption, EnumOption): pass
class stringoption(packoption, StringOption): pass
class readonlyoption(packoption, ReadonlyOption): pass
options = {
'.class': (None, 'Class'),
'.name': (None, 'Name'),
'after': (None, 'Widget'),
'anchor': ('center', 'Anchor'),
'before': (None, 'Widget'),
'expand': ('no', 'Boolean'),
'fill': ('none', 'Fill'),
'in': (None, 'Widget'),
'ipadx': (0, 'Pad'),
'ipady': (0, 'Pad'),
'padx': (0, 'Pad'),
'pady': (0, 'Pad'),
'side': ('top', 'Side'),
}
classes = {
'Anchor': (N, NE, E, SE, S, SW, W, NW, CENTER),
'Boolean': 'boolean',
'Class': 'readonly',
'Expand': 'boolean',
'Fill': (NONE, X, Y, BOTH),
'Name': 'readonly',
'Pad': 'pixel',
'Side': (TOP, RIGHT, BOTTOM, LEFT),
'Widget': 'readonly',
}
class RemotePackDialog(PackDialog):
def __init__(self, master, app, widget):
self.master = master
self.app = app
self.widget = widget
self.refresh()
self.top = Toplevel(self.master)
self.top.title(self.app + ' PackDialog')
self.top.minsize(1, 1)
self.addchoices()
def refresh(self):
try:
words = self.master.tk.splitlist(
self.master.send(self.app,
'pack',
'info',
self.widget))
except TclError, msg:
print msg
return
dict = {}
for i in range(0, len(words), 2):
key = words[i][1:]
value = words[i+1]
dict[key] = value
dict['.class'] = self.master.send(self.app,
'winfo',
'class',
self.widget)
dict['.name'] = self.widget
self.current = dict
class remotepackoption: # Mix-in class
def set(self, e=None):
self.current = self.var.get()
try:
self.dialog.master.send(
self.dialog.app,
'pack',
'config',
self.dialog.widget,
'-'+self.option,
self.dialog.master.tk.merge(
self.current))
except TclError, msg:
print msg
self.refresh()
class booleanoption(remotepackoption, BooleanOption): pass
class enumoption(remotepackoption, EnumOption): pass
class stringoption(remotepackoption, StringOption): pass
class readonlyoption(remotepackoption, ReadonlyOption): pass
class WidgetDialog(Dialog):
def __init__(self, widget):
self.widget = widget
self.klass = widget.winfo_class()
Dialog.__init__(self, widget)
def fixclasses(self):
if self.addclasses.has_key(self.klass):
classes = {}
for c in (self.classes,
self.addclasses[self.klass]):
for k in c.keys():
classes[k] = c[k]
self.classes = classes
def refresh(self):
self.configuration = self.widget.config()
self.update()
self.current['.class'] = self.widget.winfo_class()
self.current['.name'] = self.widget._w
def update(self):
self.current = {}
self.options = {}
for k, v in self.configuration.items():
if len(v) > 4:
self.current[k] = v[4]
self.options[k] = v[3], v[2] # default, klass
self.options['.class'] = (None, 'Class')
self.options['.name'] = (None, 'Name')
class widgetoption: # Mix-in class
def set(self, e=None):
self.current = self.var.get()
try:
self.dialog.widget[self.option] = self.current
except TclError, msg:
print msg
self.refresh()
class booleanoption(widgetoption, BooleanOption): pass
class enumoption(widgetoption, EnumOption): pass
class stringoption(widgetoption, StringOption): pass
class readonlyoption(widgetoption, ReadonlyOption): pass
# Universal classes
classes = {
'Anchor': (N, NE, E, SE, S, SW, W, NW, CENTER),
'Aspect': 'integer',
'Background': 'color',
'Bitmap': 'bitmap',
'BorderWidth': 'pixel',
'Class': 'readonly',
'CloseEnough': 'double',
'Command': 'command',
'Confine': 'boolean',
'Cursor': 'cursor',
'CursorWidth': 'pixel',
'DisabledForeground': 'color',
'ExportSelection': 'boolean',
'Font': 'font',
'Foreground': 'color',
'From': 'integer',
'Geometry': 'geometry',
'Height': 'pixel',
'InsertWidth': 'time',
'Justify': (LEFT, CENTER, RIGHT),
'Label': 'string',
'Length': 'pixel',
'MenuName': 'widget',
'Name': 'readonly',
'OffTime': 'time',
'OnTime': 'time',
'Orient': (HORIZONTAL, VERTICAL),
'Pad': 'pixel',
'Relief': (RAISED, SUNKEN, FLAT, RIDGE, GROOVE),
'RepeatDelay': 'time',
'RepeatInterval': 'time',
'ScrollCommand': 'command',
'ScrollIncrement': 'pixel',
'ScrollRegion': 'rectangle',
'ShowValue': 'boolean',
'SetGrid': 'boolean',
'Sliderforeground': 'color',
'SliderLength': 'pixel',
'Text': 'string',
'TickInterval': 'integer',
'To': 'integer',
'Underline': 'index',
'Variable': 'variable',
'Value': 'string',
'Width': 'pixel',
'Wrap': (NONE, CHAR, WORD),
}
# Classes that (may) differ per widget type
_tristate = {'State': (NORMAL, ACTIVE, DISABLED)}
_bistate = {'State': (NORMAL, DISABLED)}
addclasses = {
'Button': _tristate,
'Radiobutton': _tristate,
'Checkbutton': _tristate,
'Entry': _bistate,
'Text': _bistate,
'Menubutton': _tristate,
'Slider': _bistate,
}
class RemoteWidgetDialog(WidgetDialog):
def __init__(self, master, app, widget):
self.app = app
self.widget = widget
self.klass = master.send(self.app,
'winfo',
'class',
self.widget)
Dialog.__init__(self, master)
def refresh(self):
try:
items = self.master.tk.splitlist(
self.master.send(self.app,
self.widget,
'config'))
except TclError, msg:
print msg
return
dict = {}
for item in items:
words = self.master.tk.splitlist(item)
key = words[0][1:]
value = (key,) + words[1:]
dict[key] = value
self.configuration = dict
self.update()
self.current['.class'] = self.klass
self.current['.name'] = self.widget
class remotewidgetoption: # Mix-in class
def set(self, e=None):
self.current = self.var.get()
try:
self.dialog.master.send(
self.dialog.app,
self.dialog.widget,
'config',
'-'+self.option,
self.current)
except TclError, msg:
print msg
self.refresh()
class booleanoption(remotewidgetoption, BooleanOption): pass
class enumoption(remotewidgetoption, EnumOption): pass
class stringoption(remotewidgetoption, StringOption): pass
class readonlyoption(remotewidgetoption, ReadonlyOption): pass
def test():
import sys
root = Tk()
root.minsize(1, 1)
if sys.argv[1:]:
remotetest(root, sys.argv[1])
else:
frame = Frame(root, name='frame')
frame.pack(expand=1, fill=BOTH)
button = Button(frame, name='button', text='button')
button.pack(expand=1)
canvas = Canvas(frame, name='canvas')
canvas.pack()
fpd = PackDialog(frame)
fwd = WidgetDialog(frame)
bpd = PackDialog(button)
bwd = WidgetDialog(button)
cpd = PackDialog(canvas)
cwd = WidgetDialog(canvas)
root.mainloop()
def remotetest(root, app):
from listtree import listtree
list = listtree(root, app)
list.bind('<Any-Double-1>', opendialogs)
list.app = app # Pass it on to handler
def opendialogs(e):
import string
list = e.widget
sel = list.curselection()
for i in sel:
item = list.get(i)
widget = string.split(item)[0]
RemoteWidgetDialog(list, list.app, widget)
if widget == '.': continue
try:
RemotePackDialog(list, list.app, widget)
except TclError, msg:
print msg
test()