SimpleDialog.py 2.66 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11
"""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):
12 13 14 15 16 17 18
	if class_:
	    self.root = Toplevel(master, class_=class_)
	else:
	    self.root = Toplevel(master)
	if title:
	    self.root.title(title)
	    self.root.iconname(title)
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
	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)
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
	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
	widget.geometry("+%d+%d" % (x, y))
	widget.deiconify() # Become visible at the desired location
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86

    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, "
87 88
			      "the buttons below would have been glowing "
			      "in soft pink light.\n"
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
			      "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()