mirror of
https://github.com/python/cpython.git
synced 2026-05-10 14:41:01 -04:00
adfacf4e2e
is near or beyond the edge of the screen. Patch by Skip Montanaro.
112 lines
2.9 KiB
Python
112 lines
2.9 KiB
Python
"""A simple but flexible modal dialog box."""
|
|
|
|
|
|
from Tkinter import *
|
|
|
|
|
|
class SimpleDialog:
|
|
|
|
def __init__(self, master,
|
|
text='', buttons=[], default=None, cancel=None,
|
|
title=None, class_=None):
|
|
if class_:
|
|
self.root = Toplevel(master, class_=class_)
|
|
else:
|
|
self.root = Toplevel(master)
|
|
if title:
|
|
self.root.title(title)
|
|
self.root.iconname(title)
|
|
self.message = Message(self.root, text=text, aspect=400)
|
|
self.message.pack(expand=1, fill=BOTH)
|
|
self.frame = Frame(self.root)
|
|
self.frame.pack()
|
|
self.num = default
|
|
self.cancel = cancel
|
|
self.default = default
|
|
self.root.bind('<Return>', self.return_event)
|
|
for num in range(len(buttons)):
|
|
s = buttons[num]
|
|
b = Button(self.frame, text=s,
|
|
command=(lambda self=self, num=num: self.done(num)))
|
|
if num == default:
|
|
b.config(relief=RIDGE, borderwidth=8)
|
|
b.pack(side=LEFT, fill=BOTH, expand=1)
|
|
self.root.protocol('WM_DELETE_WINDOW', self.wm_delete_window)
|
|
self._set_transient(master)
|
|
|
|
def _set_transient(self, master, relx=0.5, rely=0.3):
|
|
widget = self.root
|
|
widget.withdraw() # Remain invisible while we figure out the geometry
|
|
widget.transient(master)
|
|
widget.update_idletasks() # Actualize geometry information
|
|
if master.winfo_ismapped():
|
|
m_width = master.winfo_width()
|
|
m_height = master.winfo_height()
|
|
m_x = master.winfo_rootx()
|
|
m_y = master.winfo_rooty()
|
|
else:
|
|
m_width = master.winfo_screenwidth()
|
|
m_height = master.winfo_screenheight()
|
|
m_x = m_y = 0
|
|
w_width = widget.winfo_reqwidth()
|
|
w_height = widget.winfo_reqheight()
|
|
x = m_x + (m_width - w_width) * relx
|
|
y = m_y + (m_height - w_height) * rely
|
|
if x+w_width > master.winfo_screenwidth():
|
|
x = master.winfo_screenwidth() - w_width
|
|
elif x < 0:
|
|
x = 0
|
|
if y+w_height > master.winfo_screenheight():
|
|
y = master.winfo_screenheight() - w_height
|
|
elif y < 0:
|
|
y = 0
|
|
widget.geometry("+%d+%d" % (x, y))
|
|
widget.deiconify() # Become visible at the desired location
|
|
|
|
def go(self):
|
|
self.root.grab_set()
|
|
self.root.mainloop()
|
|
self.root.destroy()
|
|
return self.num
|
|
|
|
def return_event(self, event):
|
|
if self.default is None:
|
|
self.root.bell()
|
|
else:
|
|
self.done(self.default)
|
|
|
|
def wm_delete_window(self):
|
|
if self.cancel is None:
|
|
self.root.bell()
|
|
else:
|
|
self.done(self.cancel)
|
|
|
|
def done(self, num):
|
|
self.num = num
|
|
self.root.quit()
|
|
|
|
|
|
def test():
|
|
root = Tk()
|
|
def doit(root=root):
|
|
d = SimpleDialog(root,
|
|
text="This is a test dialog. "
|
|
"Would this have been an actual dialog, "
|
|
"the buttons below would have been glowing "
|
|
"in soft pink light.\n"
|
|
"Do you believe this?",
|
|
buttons=["Yes", "No", "Cancel"],
|
|
default=0,
|
|
cancel=2,
|
|
title="Test Dialog")
|
|
print d.go()
|
|
t = Button(root, text='Test', command=doit)
|
|
t.pack()
|
|
q = Button(root, text='Quit', command=t.quit)
|
|
q.pack()
|
|
t.mainloop()
|
|
|
|
|
|
if __name__ == '__main__':
|
|
test()
|