Kaydet (Commit) 368e06b6 authored tarafından Guido van Rossum's avatar Guido van Rossum

Some restructuring.

All geometry manager methods that apply to a master widget instead of
to a slave widget have been moved to the Misc class, which is
inherited by all of Tk(), Toplevel() and Widget().  They have been
renamed to have their geometry manager name as a prefix,
e.g. pack_propagate(); the short names can still be used where
ambiguities are resolved so that pack has priority over place has
priority over grid (since this was the old rule).

Also, the method definitions in the Pack, Place and Grid classes now
all have their respective geometry manager name as a prefix
(e.g. pack_configure); the shorter names are aliases defined through
assignment.

A similar renaming has been done for all config() methods found
elsewhere; these have been renamed to configure() with config being
the alias (instead of the other way around).  (This may not make much
of a difference but the official Tk command name is now 'configure'
and it may help in debugging tracebacks.)

Finally, a new base class BaseWidget has been introduced, which
implements the methods common between Widget and Toplevel (the
difference between those two classes is that Toplevel has a different
__init__() but also that Toplevel doesn't inherit from Pack, Place or
Grid.
üst 1abbd7f3
...@@ -119,6 +119,7 @@ def getdouble(s): ...@@ -119,6 +119,7 @@ def getdouble(s):
def getboolean(s): def getboolean(s):
return _default_root.tk.getboolean(s) return _default_root.tk.getboolean(s)
# Methods defined on both toplevel and interior widgets
class Misc: class Misc:
_tclCommands = None _tclCommands = None
def destroy(self): def destroy(self):
...@@ -568,7 +569,7 @@ class Misc: ...@@ -568,7 +569,7 @@ class Misc:
root = self._root() root = self._root()
root.report_callback_exception(exc, val, tb) root.report_callback_exception(exc, val, tb)
# These used to be defined in Widget: # These used to be defined in Widget:
def config(self, cnf=None, **kw): def configure(self, cnf=None, **kw):
# XXX ought to generalize this so tag_config etc. can use it # XXX ought to generalize this so tag_config etc. can use it
if kw: if kw:
cnf = _cnfmerge((cnf, kw)) cnf = _cnfmerge((cnf, kw))
...@@ -586,17 +587,117 @@ class Misc: ...@@ -586,17 +587,117 @@ class Misc:
return (x[0][1:],) + x[1:] return (x[0][1:],) + x[1:]
apply(self.tk.call, (self._w, 'configure') apply(self.tk.call, (self._w, 'configure')
+ self._options(cnf)) + self._options(cnf))
configure = config config = configure
def cget(self, key): def cget(self, key):
return self.tk.call(self._w, 'cget', '-' + key) return self.tk.call(self._w, 'cget', '-' + key)
__getitem__ = cget __getitem__ = cget
def __setitem__(self, key, value): def __setitem__(self, key, value):
Widget.config(self, {key: value}) self.configure({key: value})
def keys(self): def keys(self):
return map(lambda x: x[0][1:], return map(lambda x: x[0][1:],
self.tk.split(self.tk.call(self._w, 'configure'))) self.tk.split(self.tk.call(self._w, 'configure')))
def __str__(self): def __str__(self):
return self._w return self._w
# Pack methods that apply to the master
_noarg_ = ['_noarg_']
def pack_propagate(self, flag=_noarg_):
if flag is Misc._noarg_:
return self._getboolean(self.tk.call(
'pack', 'propagate', self._w))
else:
self.tk.call('pack', 'propagate', self._w, flag)
propagate = pack_propagate
def pack_slaves(self):
return map(self._nametowidget,
self.tk.splitlist(
self.tk.call('pack', 'slaves', self._w)))
slaves = pack_slaves
# Place method that applies to the master
def place_slaves(self):
return map(self._nametowidget,
self.tk.splitlist(
self.tk.call(
'place', 'slaves', self._w)))
# Grid methods that apply to the master
def grid_bbox(self, column, row):
return self._getints(
self.tk.call(
'grid', 'bbox', self._w, column, row)) or None
bbox = grid_bbox
def grid_columnconfigure(self, index, cnf={}, **kw):
if type(cnf) is not DictionaryType and not kw:
options = self._options({cnf: None})
else:
options = self._options(cnf, kw)
if not options:
res = self.tk.call('grid',
'columnconfigure', self._w, index)
words = self.tk.splitlist(res)
dict = {}
for i in range(0, len(words), 2):
key = words[i][1:]
value = words[i+1]
if not value:
value = None
elif '.' in value:
value = self.tk.getdouble(value)
else:
value = self.tk.getint(value)
dict[key] = value
return dict
res = apply(self.tk.call,
('grid', 'columnconfigure', self._w, index)
+ options)
if options == ('-minsize', None):
return self.tk.getint(res) or None
elif options == ('-weight', None):
return self.tk.getdouble(res) or None
columnconfigure = grid_columnconfigure
def grid_propagate(self, flag=_noarg_):
if flag is Misc._noarg_:
return self._getboolean(self.tk.call(
'grid', 'propagate', self._w))
else:
self.tk.call('grid', 'propagate', self._w, flag)
def grid_rowconfigure(self, index, cnf={}, **kw):
if type(cnf) is not DictionaryType and not kw:
options = self._options({cnf: None})
else:
options = self._options(cnf, kw)
if not options:
res = self.tk.call('grid',
'rowconfigure', self._w, index)
words = self.tk.splitlist(res)
dict = {}
for i in range(0, len(words), 2):
key = words[i][1:]
value = words[i+1]
if not value:
value = None
elif '.' in value:
value = self.tk.getdouble(value)
else:
value = self.tk.getint(value)
dict[key] = value
return dict
res = apply(self.tk.call,
('grid', 'rowconfigure', self._w, index)
+ options)
if len(options) == 2 and options[-1] is None:
if not res: return None
# In Tk 7.5, -width can be a float
if '.' in res: return self.tk.getdouble(res)
return self.tk.getint(res)
rowconfigure = grid_rowconfigure
def grid_size(self):
return self._getints(
self.tk.call('grid', 'size', self._w)) or None
size = grid_size
def grid_slaves(self, *args):
return map(self._nametowidget,
self.tk.splitlist(
apply(self.tk.call,
('grid', 'slaves', self._w) + args)))
class CallWrapper: class CallWrapper:
def __init__(self, func, subst, widget): def __init__(self, func, subst, widget):
...@@ -767,19 +868,30 @@ class Tk(Misc, Wm): ...@@ -767,19 +868,30 @@ class Tk(Misc, Wm):
print "Exception in Tkinter callback" print "Exception in Tkinter callback"
traceback.print_exception(exc, val, tb) traceback.print_exception(exc, val, tb)
# Ideally, the classes Pack, Place and Grid disappear, the
# pack/place/grid methods are defined on the Widget class, and
# everybody uses w.pack_whatever(...) instead of Pack.whatever(w,
# ...), with pack(), place() and grid() being short for
# pack_configure(), place_configure() and grid_columnconfigure(), and
# forget() being short for pack_forget(). As a practical matter, I'm
# afraid that there is too much code out there that may be using the
# Pack, Place or Grid class, so I leave them intact -- but only as
# backwards compatibility features. Also note that those methods that
# take a master as argument (e.g. pack_propagate) have been moved to
# the Misc class (which now incorporates all methods common between
# toplevel and interior widgets). Again, for compatibility, these are
# copied into the Pack, Place or Grid class.
class Pack: class Pack:
def config(self, cnf={}, **kw): def pack_configure(self, cnf={}, **kw):
apply(self.tk.call, apply(self.tk.call,
('pack', 'configure', self._w) ('pack', 'configure', self._w)
+ self._options(cnf, kw)) + self._options(cnf, kw))
configure = config pack = configure = config = pack_configure
pack = config def pack_forget(self):
def __setitem__(self, key, value):
Pack.config({key: value})
def forget(self):
self.tk.call('pack', 'forget', self._w) self.tk.call('pack', 'forget', self._w)
pack_forget = forget forget = pack_forget
def info(self): def pack_info(self):
words = self.tk.splitlist( words = self.tk.splitlist(
self.tk.call('pack', 'info', self._w)) self.tk.call('pack', 'info', self._w))
dict = {} dict = {}
...@@ -790,23 +902,12 @@ class Pack: ...@@ -790,23 +902,12 @@ class Pack:
value = self._nametowidget(value) value = self._nametowidget(value)
dict[key] = value dict[key] = value
return dict return dict
pack_info = info info = pack_info
_noarg_ = ['_noarg_'] propagate = pack_propagate = Misc.pack_propagate
def propagate(self, flag=_noarg_): slaves = pack_slaves = Misc.pack_slaves
if flag is Pack._noarg_:
return self._getboolean(self.tk.call(
'pack', 'propagate', self._w))
else:
self.tk.call('pack', 'propagate', self._w, flag)
pack_propagate = propagate
def slaves(self):
return map(self._nametowidget,
self.tk.splitlist(
self.tk.call('pack', 'slaves', self._w)))
pack_slaves = slaves
class Place: class Place:
def config(self, cnf={}, **kw): def place_configure(self, cnf={}, **kw):
for k in ['in_']: for k in ['in_']:
if kw.has_key(k): if kw.has_key(k):
kw[k[:-1]] = kw[k] kw[k[:-1]] = kw[k]
...@@ -814,14 +915,11 @@ class Place: ...@@ -814,14 +915,11 @@ class Place:
apply(self.tk.call, apply(self.tk.call,
('place', 'configure', self._w) ('place', 'configure', self._w)
+ self._options(cnf, kw)) + self._options(cnf, kw))
configure = config place = configure = config = place_configure
place = config def place_forget(self):
def __setitem__(self, key, value):
Place.config({key: value})
def forget(self):
self.tk.call('place', 'forget', self._w) self.tk.call('place', 'forget', self._w)
place_forget = forget forget = place_forget
def info(self): def place_info(self):
words = self.tk.splitlist( words = self.tk.splitlist(
self.tk.call('place', 'info', self._w)) self.tk.call('place', 'info', self._w))
dict = {} dict = {}
...@@ -832,44 +930,22 @@ class Place: ...@@ -832,44 +930,22 @@ class Place:
value = self._nametowidget(value) value = self._nametowidget(value)
dict[key] = value dict[key] = value
return dict return dict
place_info = info info = place_info
def slaves(self): slaves = place_slaves = Misc.place_slaves
return map(self._nametowidget,
self.tk.splitlist(
self.tk.call(
'place', 'slaves', self._w)))
place_slaves = slaves
class Grid: class Grid:
# Thanks to Masazumi Yoshikawa (yosikawa@isi.edu) # Thanks to Masazumi Yoshikawa (yosikawa@isi.edu)
def config(self, cnf={}, **kw): def grid_configure(self, cnf={}, **kw):
apply(self.tk.call, apply(self.tk.call,
('grid', 'configure', self._w) ('grid', 'configure', self._w)
+ self._options(cnf, kw)) + self._options(cnf, kw))
grid = config grid = configure = config = grid_configure
def __setitem__(self, key, value): bbox = grid_bbox = Misc.grid_bbox
Grid.config({key: value}) columnconfigure = grid_columnconfigure = Misc.grid_columnconfigure
def bbox(self, column, row): def grid_forget(self):
return self._getints(
self.tk.call(
'grid', 'bbox', self._w, column, row)) or None
grid_bbox = bbox
def columnconfigure(self, index, cnf={}, **kw):
if type(cnf) is not DictionaryType and not kw:
options = self._options({cnf: None})
else:
options = self._options(cnf, kw)
res = apply(self.tk.call,
('grid', 'columnconfigure', self._w, index)
+ options)
if options == ('-minsize', None):
return self.tk.getint(res) or None
elif options == ('-weight', None):
return self.tk.getdouble(res) or None
def forget(self):
self.tk.call('grid', 'forget', self._w) self.tk.call('grid', 'forget', self._w)
grid_forget = forget forget = grid_forget
def info(self): def grid_info(self):
words = self.tk.splitlist( words = self.tk.splitlist(
self.tk.call('grid', 'info', self._w)) self.tk.call('grid', 'info', self._w))
dict = {} dict = {}
...@@ -880,42 +956,18 @@ class Grid: ...@@ -880,42 +956,18 @@ class Grid:
value = self._nametowidget(value) value = self._nametowidget(value)
dict[key] = value dict[key] = value
return dict return dict
grid_info = info info = grid_info
def location(self, x, y): def grid_location(self, x, y):
return self._getints( return self._getints(
self.tk.call( self.tk.call(
'grid', 'location', self._w, x, y)) or None 'grid', 'location', self._w, x, y)) or None
_noarg_ = ['_noarg_'] location = grid_location
def propagate(self, flag=_noarg_): propagate = grid_propagate = Misc.grid_propagate
if flag is Grid._noarg_: rowconfigure = grid_rowconfigure = Misc.grid_rowconfigure
return self._getboolean(self.tk.call( size = grid_size = Misc.grid_size
'grid', 'propagate', self._w)) slaves = grid_slaves = Misc.grid_slaves
else:
self.tk.call('grid', 'propagate', self._w, flag)
grid_propagate = propagate
def rowconfigure(self, index, cnf={}, **kw):
if type(cnf) is not DictionaryType and not kw:
options = self._options({cnf: None})
else:
options = self._options(cnf, kw)
res = apply(self.tk.call,
('grid', 'rowconfigure', self._w, index)
+ options)
if options == ('-minsize', None):
return self.tk.getint(res) or None
elif options == ('-weight', None):
return self.tk.getdouble(res) or None
def size(self):
return self._getints(
self.tk.call('grid', 'size', self._w)) or None
def slaves(self, *args):
return map(self._nametowidget,
self.tk.splitlist(
apply(self.tk.call,
('grid', 'slaves', self._w) + args)))
grid_slaves = slaves
class Widget(Misc, Pack, Place, Grid): class BaseWidget(Misc):
def _setup(self, master, cnf): def _setup(self, master, cnf):
global _default_root global _default_root
if not master: if not master:
...@@ -945,7 +997,7 @@ class Widget(Misc, Pack, Place, Grid): ...@@ -945,7 +997,7 @@ class Widget(Misc, Pack, Place, Grid):
if kw: if kw:
cnf = _cnfmerge((cnf, kw)) cnf = _cnfmerge((cnf, kw))
self.widgetName = widgetName self.widgetName = widgetName
Widget._setup(self, master, cnf) BaseWidget._setup(self, master, cnf)
classes = [] classes = []
for k in cnf.keys(): for k in cnf.keys():
if type(k) is ClassType: if type(k) is ClassType:
...@@ -954,7 +1006,7 @@ class Widget(Misc, Pack, Place, Grid): ...@@ -954,7 +1006,7 @@ class Widget(Misc, Pack, Place, Grid):
apply(self.tk.call, apply(self.tk.call,
(widgetName, self._w) + extra + self._options(cnf)) (widgetName, self._w) + extra + self._options(cnf))
for k, v in classes: for k, v in classes:
k.config(self, v) k.configure(self, v)
def destroy(self): def destroy(self):
for c in self.children.values(): c.destroy() for c in self.children.values(): c.destroy()
if self.master.children.has_key(self._name): if self.master.children.has_key(self._name):
...@@ -964,7 +1016,10 @@ class Widget(Misc, Pack, Place, Grid): ...@@ -964,7 +1016,10 @@ class Widget(Misc, Pack, Place, Grid):
def _do(self, name, args=()): def _do(self, name, args=()):
return apply(self.tk.call, (self._w, name) + args) return apply(self.tk.call, (self._w, name) + args)
class Toplevel(Widget, Wm): class Widget(BaseWidget, Pack, Place, Grid):
pass
class Toplevel(BaseWidget, Wm):
def __init__(self, master=None, cnf={}, **kw): def __init__(self, master=None, cnf={}, **kw):
if kw: if kw:
cnf = _cnfmerge((cnf, kw)) cnf = _cnfmerge((cnf, kw))
...@@ -979,7 +1034,7 @@ class Toplevel(Widget, Wm): ...@@ -979,7 +1034,7 @@ class Toplevel(Widget, Wm):
else: opt = '-'+wmkey else: opt = '-'+wmkey
extra = extra + (opt, val) extra = extra + (opt, val)
del cnf[wmkey] del cnf[wmkey]
Widget.__init__(self, master, 'toplevel', cnf, {}, extra) BaseWidget.__init__(self, master, 'toplevel', cnf, {}, extra)
root = self._root() root = self._root()
self.iconname(root.iconname()) self.iconname(root.iconname())
self.title(root.title()) self.title(root.title())
...@@ -1119,7 +1174,7 @@ class Canvas(Widget): ...@@ -1119,7 +1174,7 @@ class Canvas(Widget):
self._do('insert', args) self._do('insert', args)
def itemcget(self, tagOrId, option): def itemcget(self, tagOrId, option):
return self._do('itemcget', (tagOrId, '-'+option)) return self._do('itemcget', (tagOrId, '-'+option))
def itemconfig(self, tagOrId, cnf=None, **kw): def itemconfigure(self, tagOrId, cnf=None, **kw):
if cnf is None and not kw: if cnf is None and not kw:
cnf = {} cnf = {}
for x in self.tk.split( for x in self.tk.split(
...@@ -1132,7 +1187,7 @@ class Canvas(Widget): ...@@ -1132,7 +1187,7 @@ class Canvas(Widget):
return (x[0][1:],) + x[1:] return (x[0][1:],) + x[1:]
self._do('itemconfigure', (tagOrId,) self._do('itemconfigure', (tagOrId,)
+ self._options(cnf, kw)) + self._options(cnf, kw))
itemconfigure = itemconfig itemconfig = itemconfigure
def lower(self, *args): def lower(self, *args):
self._do('lower', args) self._do('lower', args)
def move(self, *args): def move(self, *args):
...@@ -1360,7 +1415,7 @@ class Menu(Widget): ...@@ -1360,7 +1415,7 @@ class Menu(Widget):
self.insert(index, 'separator', cnf or kw) self.insert(index, 'separator', cnf or kw)
def delete(self, index1, index2=None): def delete(self, index1, index2=None):
self.tk.call(self._w, 'delete', index1, index2) self.tk.call(self._w, 'delete', index1, index2)
def entryconfig(self, index, cnf=None, **kw): def entryconfigure(self, index, cnf=None, **kw):
if cnf is None and not kw: if cnf is None and not kw:
cnf = {} cnf = {}
for x in self.tk.split(apply(self.tk.call, for x in self.tk.split(apply(self.tk.call,
...@@ -1373,7 +1428,7 @@ class Menu(Widget): ...@@ -1373,7 +1428,7 @@ class Menu(Widget):
return (x[0][1:],) + x[1:] return (x[0][1:],) + x[1:]
apply(self.tk.call, (self._w, 'entryconfigure', index) apply(self.tk.call, (self._w, 'entryconfigure', index)
+ self._options(cnf, kw)) + self._options(cnf, kw))
entryconfigure = entryconfig entryconfig = entryconfigure
def index(self, index): def index(self, index):
i = self.tk.call(self._w, 'index', index) i = self.tk.call(self._w, 'index', index)
if i == 'none': return None if i == 'none': return None
...@@ -1512,7 +1567,7 @@ class Text(Widget): ...@@ -1512,7 +1567,7 @@ class Text(Widget):
if option[-1:] == '_': if option[-1:] == '_':
option = option[:-1] option = option[:-1]
return self.tk.call(self._w, 'tag', 'cget', tagName, option) return self.tk.call(self._w, 'tag', 'cget', tagName, option)
def tag_config(self, tagName, cnf={}, **kw): def tag_configure(self, tagName, cnf={}, **kw):
if type(cnf) == StringType: if type(cnf) == StringType:
x = self.tk.split(self.tk.call( x = self.tk.split(self.tk.call(
self._w, 'tag', 'configure', tagName, '-'+cnf)) self._w, 'tag', 'configure', tagName, '-'+cnf))
...@@ -1520,7 +1575,7 @@ class Text(Widget): ...@@ -1520,7 +1575,7 @@ class Text(Widget):
apply(self.tk.call, apply(self.tk.call,
(self._w, 'tag', 'configure', tagName) (self._w, 'tag', 'configure', tagName)
+ self._options(cnf, kw)) + self._options(cnf, kw))
tag_configure = tag_config tag_config = tag_configure
def tag_delete(self, *tagNames): def tag_delete(self, *tagNames):
apply(self.tk.call, (self._w, 'tag', 'delete') + tagNames) apply(self.tk.call, (self._w, 'tag', 'delete') + tagNames)
def tag_lower(self, tagName, belowThis=None): def tag_lower(self, tagName, belowThis=None):
...@@ -1542,7 +1597,7 @@ class Text(Widget): ...@@ -1542,7 +1597,7 @@ class Text(Widget):
self._w, 'tag', 'remove', tagName, index1, index2) self._w, 'tag', 'remove', tagName, index1, index2)
def window_cget(self, index, option): def window_cget(self, index, option):
return self.tk.call(self._w, 'window', 'cget', index, option) return self.tk.call(self._w, 'window', 'cget', index, option)
def window_config(self, index, cnf={}, **kw): def window_configure(self, index, cnf={}, **kw):
if type(cnf) == StringType: if type(cnf) == StringType:
x = self.tk.split(self.tk.call( x = self.tk.split(self.tk.call(
self._w, 'window', 'configure', self._w, 'window', 'configure',
...@@ -1551,7 +1606,7 @@ class Text(Widget): ...@@ -1551,7 +1606,7 @@ class Text(Widget):
apply(self.tk.call, apply(self.tk.call,
(self._w, 'window', 'configure', index) (self._w, 'window', 'configure', index)
+ self._options(cnf, kw)) + self._options(cnf, kw))
window_configure = window_config window_config = window_configure
def window_create(self, index, cnf={}, **kw): def window_create(self, index, cnf={}, **kw):
apply(self.tk.call, apply(self.tk.call,
(self._w, 'window', 'create', index) (self._w, 'window', 'create', index)
...@@ -1629,7 +1684,7 @@ class Image: ...@@ -1629,7 +1684,7 @@ class Image:
self.tk.call(self.name, 'configure', '-'+key, value) self.tk.call(self.name, 'configure', '-'+key, value)
def __getitem__(self, key): def __getitem__(self, key):
return self.tk.call(self.name, 'configure', '-'+key) return self.tk.call(self.name, 'configure', '-'+key)
def config(self, **kw): def configure(self, **kw):
res = () res = ()
for k, v in _cnfmerge(kw).items(): for k, v in _cnfmerge(kw).items():
if v is not None: if v is not None:
...@@ -1638,7 +1693,7 @@ class Image: ...@@ -1638,7 +1693,7 @@ class Image:
v = self._register(v) v = self._register(v)
res = res + ('-'+k, v) res = res + ('-'+k, v)
apply(self.tk.call, (self.name, 'config') + res) apply(self.tk.call, (self.name, 'config') + res)
configure = config config = configure
def height(self): def height(self):
return self.tk.getint( return self.tk.getint(
self.tk.call('image', 'height', self.name)) self.tk.call('image', 'height', self.name))
...@@ -1724,7 +1779,7 @@ def _test(): ...@@ -1724,7 +1779,7 @@ def _test():
label = Label(root, text="Proof-of-existence test for Tk") label = Label(root, text="Proof-of-existence test for Tk")
label.pack() label.pack()
test = Button(root, text="Click me!", test = Button(root, text="Click me!",
command=lambda root=root: root.test.config( command=lambda root=root: root.test.configure(
text="[%s]" % root.test['text'])) text="[%s]" % root.test['text']))
test.pack() test.pack()
root.test = test root.test = test
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment