Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit de99d31

Browse files
committed
Check in another copy of tktools.py...
1 parent 06981c3 commit de99d31

1 file changed

Lines changed: 367 additions & 0 deletions

File tree

Tools/webchecker/tktools.py

Lines changed: 367 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,367 @@
1+
"""Assorted Tk-related subroutines used in Grail."""
2+
3+
4+
import string
5+
from types import *
6+
from Tkinter import *
7+
8+
def _clear_entry_widget(event):
9+
try:
10+
widget = event.widget
11+
widget.delete(0, INSERT)
12+
except: pass
13+
def install_keybindings(root):
14+
root.bind_class('Entry', '<Control-u>', _clear_entry_widget)
15+
16+
17+
def make_toplevel(master, title=None, class_=None):
18+
"""Create a Toplevel widget.
19+
20+
This is a shortcut for a Toplevel() instantiation plus calls to
21+
set the title and icon name of the widget.
22+
23+
"""
24+
25+
if class_:
26+
widget = Toplevel(master, class_=class_)
27+
else:
28+
widget = Toplevel(master)
29+
if title:
30+
widget.title(title)
31+
widget.iconname(title)
32+
return widget
33+
34+
def set_transient(widget, master, relx=0.5, rely=0.3, expose=1):
35+
"""Make an existing toplevel widget transient for a master.
36+
37+
The widget must exist but should not yet have been placed; in
38+
other words, this should be called after creating all the
39+
subwidget but before letting the user interact.
40+
"""
41+
42+
widget.withdraw() # Remain invisible while we figure out the geometry
43+
widget.transient(master)
44+
widget.update_idletasks() # Actualize geometry information
45+
if master.winfo_ismapped():
46+
m_width = master.winfo_width()
47+
m_height = master.winfo_height()
48+
m_x = master.winfo_rootx()
49+
m_y = master.winfo_rooty()
50+
else:
51+
m_width = master.winfo_screenwidth()
52+
m_height = master.winfo_screenheight()
53+
m_x = m_y = 0
54+
w_width = widget.winfo_reqwidth()
55+
w_height = widget.winfo_reqheight()
56+
x = m_x + (m_width - w_width) * relx
57+
y = m_y + (m_height - w_height) * rely
58+
widget.geometry("+%d+%d" % (x, y))
59+
if expose:
60+
widget.deiconify() # Become visible at the desired location
61+
return widget
62+
63+
64+
def make_scrollbars(parent, hbar, vbar, pack=1, class_=None, name=None,
65+
takefocus=0):
66+
67+
"""Subroutine to create a frame with scrollbars.
68+
69+
This is used by make_text_box and similar routines.
70+
71+
Note: the caller is responsible for setting the x/y scroll command
72+
properties (e.g. by calling set_scroll_commands()).
73+
74+
Return a tuple containing the hbar, the vbar, and the frame, where
75+
hbar and vbar are None if not requested.
76+
77+
"""
78+
if class_:
79+
if name: frame = Frame(parent, class_=class_, name=name)
80+
else: frame = Frame(parent, class_=class_)
81+
else:
82+
if name: frame = Frame(parent, name=name)
83+
else: frame = Frame(parent)
84+
85+
if pack:
86+
frame.pack(fill=BOTH, expand=1)
87+
88+
corner = None
89+
if vbar:
90+
if not hbar:
91+
vbar = Scrollbar(frame, takefocus=takefocus)
92+
vbar.pack(fill=Y, side=RIGHT)
93+
else:
94+
vbarframe = Frame(frame, borderwidth=0)
95+
vbarframe.pack(fill=Y, side=RIGHT)
96+
vbar = Scrollbar(frame, name="vbar", takefocus=takefocus)
97+
vbar.pack(in_=vbarframe, expand=1, fill=Y, side=TOP)
98+
sbwidth = vbar.winfo_reqwidth()
99+
corner = Frame(vbarframe, width=sbwidth, height=sbwidth)
100+
corner.propagate(0)
101+
corner.pack(side=BOTTOM)
102+
else:
103+
vbar = None
104+
105+
if hbar:
106+
hbar = Scrollbar(frame, orient=HORIZONTAL, name="hbar",
107+
takefocus=takefocus)
108+
hbar.pack(fill=X, side=BOTTOM)
109+
else:
110+
hbar = None
111+
112+
return hbar, vbar, frame
113+
114+
115+
def set_scroll_commands(widget, hbar, vbar):
116+
117+
"""Link a scrollable widget to its scroll bars.
118+
119+
The scroll bars may be empty.
120+
121+
"""
122+
123+
if vbar:
124+
widget['yscrollcommand'] = (vbar, 'set')
125+
vbar['command'] = (widget, 'yview')
126+
127+
if hbar:
128+
widget['xscrollcommand'] = (hbar, 'set')
129+
hbar['command'] = (widget, 'xview')
130+
131+
widget.vbar = vbar
132+
widget.hbar = hbar
133+
134+
135+
def make_text_box(parent, width=0, height=0, hbar=0, vbar=1,
136+
fill=BOTH, expand=1, wrap=WORD, pack=1,
137+
class_=None, name=None, takefocus=None):
138+
139+
"""Subroutine to create a text box.
140+
141+
Create:
142+
- a both-ways filling and expanding frame, containing:
143+
- a text widget on the left, and
144+
- possibly a vertical scroll bar on the right.
145+
- possibly a horizonta; scroll bar at the bottom.
146+
147+
Return the text widget and the frame widget.
148+
149+
"""
150+
hbar, vbar, frame = make_scrollbars(parent, hbar, vbar, pack,
151+
class_=class_, name=name,
152+
takefocus=takefocus)
153+
154+
widget = Text(frame, wrap=wrap, name="text")
155+
if width: widget.config(width=width)
156+
if height: widget.config(height=height)
157+
widget.pack(expand=expand, fill=fill, side=LEFT)
158+
159+
set_scroll_commands(widget, hbar, vbar)
160+
161+
return widget, frame
162+
163+
164+
def make_list_box(parent, width=0, height=0, hbar=0, vbar=1,
165+
fill=BOTH, expand=1, pack=1, class_=None, name=None,
166+
takefocus=None):
167+
168+
"""Subroutine to create a list box.
169+
170+
Like make_text_box().
171+
"""
172+
hbar, vbar, frame = make_scrollbars(parent, hbar, vbar, pack,
173+
class_=class_, name=name,
174+
takefocus=takefocus)
175+
176+
widget = Listbox(frame, name="listbox")
177+
if width: widget.config(width=width)
178+
if height: widget.config(height=height)
179+
widget.pack(expand=expand, fill=fill, side=LEFT)
180+
181+
set_scroll_commands(widget, hbar, vbar)
182+
183+
return widget, frame
184+
185+
186+
def make_canvas(parent, width=0, height=0, hbar=1, vbar=1,
187+
fill=BOTH, expand=1, pack=1, class_=None, name=None,
188+
takefocus=None):
189+
190+
"""Subroutine to create a canvas.
191+
192+
Like make_text_box().
193+
194+
"""
195+
196+
hbar, vbar, frame = make_scrollbars(parent, hbar, vbar, pack,
197+
class_=class_, name=name,
198+
takefocus=takefocus)
199+
200+
widget = Canvas(frame, scrollregion=(0, 0, width, height), name="canvas")
201+
if width: widget.config(width=width)
202+
if height: widget.config(height=height)
203+
widget.pack(expand=expand, fill=fill, side=LEFT)
204+
205+
set_scroll_commands(widget, hbar, vbar)
206+
207+
return widget, frame
208+
209+
210+
211+
def make_form_entry(parent, label, borderwidth=None):
212+
213+
"""Subroutine to create a form entry.
214+
215+
Create:
216+
- a horizontally filling and expanding frame, containing:
217+
- a label on the left, and
218+
- a text entry on the right.
219+
220+
Return the entry widget and the frame widget.
221+
222+
"""
223+
224+
frame = Frame(parent)
225+
frame.pack(fill=X)
226+
227+
label = Label(frame, text=label)
228+
label.pack(side=LEFT)
229+
230+
if borderwidth is None:
231+
entry = Entry(frame, relief=SUNKEN)
232+
else:
233+
entry = Entry(frame, relief=SUNKEN, borderwidth=borderwidth)
234+
entry.pack(side=LEFT, fill=X, expand=1)
235+
236+
return entry, frame
237+
238+
# This is a slightly modified version of the function above. This
239+
# version does the proper alighnment of labels with their fields. It
240+
# should probably eventually replace make_form_entry altogether.
241+
#
242+
# The one annoying bug is that the text entry field should be
243+
# expandable while still aligning the colons. This doesn't work yet.
244+
#
245+
def make_labeled_form_entry(parent, label, entrywidth=20, entryheight=1,
246+
labelwidth=0, borderwidth=None,
247+
takefocus=None):
248+
"""Subroutine to create a form entry.
249+
250+
Create:
251+
- a horizontally filling and expanding frame, containing:
252+
- a label on the left, and
253+
- a text entry on the right.
254+
255+
Return the entry widget and the frame widget.
256+
"""
257+
if label and label[-1] != ':': label = label + ':'
258+
259+
frame = Frame(parent)
260+
261+
label = Label(frame, text=label, width=labelwidth, anchor=E)
262+
label.pack(side=LEFT)
263+
if entryheight == 1:
264+
if borderwidth is None:
265+
entry = Entry(frame, relief=SUNKEN, width=entrywidth)
266+
else:
267+
entry = Entry(frame, relief=SUNKEN, width=entrywidth,
268+
borderwidth=borderwidth)
269+
entry.pack(side=RIGHT, expand=1, fill=X)
270+
frame.pack(fill=X)
271+
else:
272+
entry = make_text_box(frame, entrywidth, entryheight, 1, 1,
273+
takefocus=takefocus)
274+
frame.pack(fill=BOTH, expand=1)
275+
276+
return entry, frame, label
277+
278+
279+
def make_double_frame(master=None, class_=None, name=None, relief=RAISED,
280+
borderwidth=1):
281+
"""Create a pair of frames suitable for 'hosting' a dialog."""
282+
if name:
283+
if class_: frame = Frame(master, class_=class_, name=name)
284+
else: frame = Frame(master, name=name)
285+
else:
286+
if class_: frame = Frame(master, class_=class_)
287+
else: frame = Frame(master)
288+
top = Frame(frame, name="topframe", relief=relief,
289+
borderwidth=borderwidth)
290+
bottom = Frame(frame, name="bottomframe")
291+
bottom.pack(fill=X, padx='1m', pady='1m', side=BOTTOM)
292+
top.pack(expand=1, fill=BOTH, padx='1m', pady='1m')
293+
frame.pack(expand=1, fill=BOTH)
294+
top = Frame(top)
295+
top.pack(expand=1, fill=BOTH, padx='2m', pady='2m')
296+
297+
return frame, top, bottom
298+
299+
300+
def make_group_frame(master, name=None, label=None, fill=Y,
301+
side=None, expand=None, font=None):
302+
"""Create nested frames with a border and optional label.
303+
304+
The outer frame is only used to provide the decorative border, to
305+
control packing, and to host the label. The inner frame is packed
306+
to fill the outer frame and should be used as the parent of all
307+
sub-widgets. Only the inner frame is returned.
308+
309+
"""
310+
font = font or "-*-helvetica-medium-r-normal-*-*-100-*-*-*-*-*-*"
311+
outer = Frame(master, borderwidth=2, relief=GROOVE)
312+
outer.pack(expand=expand, fill=fill, side=side)
313+
if label:
314+
Label(outer, text=label, font=font, anchor=W).pack(fill=X)
315+
inner = Frame(master, borderwidth='1m', name=name)
316+
inner.pack(expand=1, fill=BOTH, in_=outer)
317+
inner.forget = outer.forget
318+
return inner
319+
320+
321+
def unify_button_widths(*buttons):
322+
"""Make buttons passed in all have the same width.
323+
324+
Works for labels and other widgets with the 'text' option.
325+
326+
"""
327+
wid = 0
328+
for btn in buttons:
329+
wid = max(wid, len(btn["text"]))
330+
for btn in buttons:
331+
btn["width"] = wid
332+
333+
334+
def flatten(msg):
335+
"""Turn a list or tuple into a single string -- recursively."""
336+
t = type(msg)
337+
if t in (ListType, TupleType):
338+
msg = string.join(map(flatten, msg))
339+
elif t is ClassType:
340+
msg = msg.__name__
341+
else:
342+
msg = str(msg)
343+
return msg
344+
345+
346+
def boolean(s):
347+
"""Test whether a string is a Tk boolean, without error checking."""
348+
if string.lower(s) in ('', '0', 'no', 'off', 'false'): return 0
349+
else: return 1
350+
351+
352+
def test():
353+
"""Test make_text_box(), make_form_entry(), flatten(), boolean()."""
354+
import sys
355+
root = Tk()
356+
entry, eframe = make_form_entry(root, 'Boolean:')
357+
text, tframe = make_text_box(root)
358+
def enter(event, entry=entry, text=text):
359+
s = boolean(entry.get()) and '\nyes' or '\nno'
360+
text.insert('end', s)
361+
entry.bind('<Return>', enter)
362+
entry.insert(END, flatten(sys.argv))
363+
root.mainloop()
364+
365+
366+
if __name__ == '__main__':
367+
test()

0 commit comments

Comments
 (0)