By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,148 Members | 759 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,148 IT Pros & Developers. It's quick & easy.

Tkinter and dialogs

P: n/a
I'm trying unsuccessfully to do something in Tk that I though would be
easy. After Googling this all day, I think I need some help. I am
admittedly very novice with Tk (I started with it yesterday), so I am
sure I am overlooking something simple.

The basic idea is that my application will consist of a series of modal
dialogs, that are chained together in "wizard" fashion. There will be
some processing in between dialogs, but for the most part, the user will
do some interaction with each dialog and then click "Next" or
"Previous". My thinking was that the main (root) Tk window would be
hidden and that each dialog would be modal and child to that hidden
window. Is this a reasonable way to do this in Tkinter?

I grabbed the "Dialog" class from effbot's site figuring that was good
starting point. I did modify it somewhat to convert to the grid layout
manager, based on advice in the New Mexico Tech Tkinter Reference (by
John Shipman).

When I run this (Ubuntu 6.06), I get no windows, not even the root Tk one.

Any ideas???

Thanks,

Don


#!/usr/bin/env python
from Tkinter import *

root = None

class Dialog(Toplevel):

def __init__(self, parent, title = None):
Toplevel.__init__(self, parent)
self.transient(parent)

if title:
self.title(title)

print repr(parent)
self.parent = parent
self.result = None

#body = Frame(self)
#self.initial_focus = self.body(body)
#body.pack(padx=5, pady=5)

self.initial_focus = self.body(self)

self.buttonbox()

self.bind("<Return>", self.ok)
self.bind("<Escape>", self.cancel)

self.grab_set()

if not self.initial_focus:
self.initial_focus = self

self.protocol("WM_DELETE_WINDOW", self.cancel)

self.geometry("+%d+%d" % (parent.winfo_rootx()+50,
parent.winfo_rooty()+50))

self.initial_focus.focus_set()

self.wait_window(self)
#
# construction hooks

def body(self, master):
# create dialog body. return widget that should have
# initial focus. this method should be overridden
pass

def buttonbox(self):
# add standard button box. override if you don't want the
# standard buttons

box = Frame(self)

w = Button(box, text="OK", width=10, command=self.ok,
default=ACTIVE)
w.pack(side=LEFT, padx=5, pady=5)
w = Button(box, text="Cancel", width=10, command=self.cancel)
w.pack(side=LEFT, padx=5, pady=5)

self.bind("<Return>", self.ok)
self.bind("<Escape>", self.cancel)

box.pack()

#
# standard button semantics

def ok(self, event=None):
if not self.validate():
self.initial_focus.focus_set() # put focus back
return

self.withdraw()
self.update_idletasks()
self.apply()
self.cancel()

def cancel(self, event=None):
# put focus back to the parent window
self.parent.focus_set()
self.destroy()

#
# command hooks

def validate(self):
print "validate"
return True # override

def apply(self):
print "apply"
pass # override
class WelcomeDialog(Dialog):
def body(self, master):

Label(master, text="First:").grid(row=0, sticky=W)
Label(master, text="Second:").grid(row=1, sticky=W)

self.e1 = Entry(master)
self.e2 = Entry(master)

self.e1.grid(row=0, column=1)
self.e2.grid(row=1, column=1)

self.cb = Checkbutton(master, text="Hardcopy")
self.cb.grid(row=2, columnspan=2, sticky=W)

self.w1 = Button(master, text="OK", width=10, command=self.ok,
default=ACTIVE)
#w.pack(side=LEFT, padx=5, pady=5)
self.w1.grid(row=3, column=0)
self.w2 = Button(master, text="Cancel", width=10,
command=self.cancel)
#w.pack(side=LEFT, padx=5, pady=5)
self.w2.grid(row=3, column=1)
def apply(self):
print "apply"
first = int(self.e1.get())
second = int(self.e2.get())
self.result = first, second

def buttonbox(self):
pass
def show_ui():
welcome = WelcomeDialog(root, "test1")

global root
root = Tk()
root.after_idle(show_ui)
root.mainloop()
Jul 6 '06 #1
Share this Question
Share on Google+
3 Replies


P: n/a
dwelch91 wrote:
I get no windows, not even the root Tk one.
no time to dig deeper into this right now, but the culprit is probably a
combination of this line

self.transient(parent)

and the after_idle approach to create the Dialog (Toplevel) window. the
transient call tells Tkinter to make the new dialogue window dependent
on the parent (which is the root Tk window in this case), but that
window hasn't been created yet when you get to transient, so Tk ends up
waiting for something that obviously never happens...

as a workaround, you can either remove the transient call, or insert an
explicit root.update() before the root.after_idle() call.
root = None
global root
root = Tk()
unrelated to your question: "global" is used in a local scope (a
function or method) to indicate that a variable that you assign to is a
global variable. for the full story, see

http://pyref.infogami.com/naming-and-binding

</F>

Jul 6 '06 #2

P: n/a
In <44********@usenet01.boi.hp.com>, dwelch91 wrote:
When I run this (Ubuntu 6.06), I get no windows, not even the root Tk one.

Any ideas???

[…]

global root
root = Tk()
root.after_idle(show_ui)
root.mainloop()
What is this `after_idle()` call supposed to do? The main loop isn't
running yet. If you just call `show_ui()` you should get some windows.

The ``global`` is unnecessary by the way. It even generates a warning:

test.py:0: SyntaxWarning: name 'root' is assigned to before global
declaration

Ciao,
Marc 'BlackJack' Rintsch
Jul 6 '06 #3

P: n/a
dwelch91 wrote:
I'm trying unsuccessfully to do something in Tk that I though would be
easy.
It is easy.
The basic idea is that my application will consist of a series of modal
dialogs, that are chained together in "wizard" fashion.
Didn't have time to get into the code you posted. Just think that the
solution I use might be of some help.

#!/usr/bin/env python
import Tkinter
class PrevNextPane(Tkinter.Frame):
def __init__(self,master):
self.master=master
Tkinter.Frame.__init__(self,master)

self.prvBtn=Tkinter.Button(self,text="Prev",comman d=self.do_prev).grid(row=0,column=0)

self.nxtBtn=Tkinter.Button(self,text="Next",comman d=self.do_next).grid(row=0,column=1)
def do_next(self):
self.master.paneNumber+=1
self.master.displayPane()

def do_prev(self):
self.master.paneNumber-=1
self.master.displayPane()

class Pane0(Tkinter.Frame):
def __init__(self,master):
Tkinter.Frame.__init__(self,master)
for i in range(5):
Tkinter.Entry(self).grid(row=i,column=0)

class Pane1(Tkinter.Frame):
def __init__(self,master):
Tkinter.Frame.__init__(self,master)
for i in range(5):
Tkinter.Label(self,text="Label %s"% i).grid(row=i,column=0)

class Pane2(Tkinter.Frame):
def __init__(self,master):
Tkinter.Frame.__init__(self,master)
for i in range(5):
Tkinter.Button(self,text="BtnPane2-%s"%
i).grid(row=i,column=0)

class Wizard(Tkinter.Tk):
def __init__(self):
Tkinter.Tk.__init__(self)
self.topPane=None
self.prevNextPane=PrevNextPane(self).pack(side=Tki nter.BOTTOM)
self.paneNumber=0
self.displayPane()
def displayPane(self):
if self.topPane!=None:
self.topPane.forget()
try:
self.topPane=globals()["Pane%s"% self.paneNumber](self)
except KeyError:
pass
self.topPane.pack(side=Tkinter.TOP)

if __name__=="__main__":
w=Wizard()
w.mainloop()

Jul 8 '06 #4

This discussion thread is closed

Replies have been disabled for this discussion.