[Tutor] Getting info from Toplevel() window?

Michael P. Reilly arcege@speakeasy.net
Tue, 22 May 2001 10:09:18 -0400 (EDT)


Ryan Booz wrote
> 
> I'm wondering if someone can help me with this question.  I have a
> simple program that puts a Proverb in a small Tk window when students
> log into the computers here at school.  I've been trying to add the
> ability to let them add Proverbs of their own.  They hit a button that
> brings up a second Toplevel() window which has three entry fields.  From
> that window, they hit an "add" button that should write the proverb.
> However, it does not grab the info out of the fields.  The separators I
> used for the split function (to separate the chapter, verse, and
> Proverb) gets written, so the function does work (mostly), but I can't
> figure out how to get the info from the window!  Thanks a bunch.  Slowly
> moving up the learning curve!

In your lambda, you are passing the result of the "get" methods of
the entry widgets.  Instead you will want to just pass the
widgets themselves and call get in the write_prov function.  The
problem is that calling the get() methods when the button is created
means that the entry widgets are empty, and the values will be empty
strings.  If you wait until the write_prov function, then the button
has been pressed and the entry widgets have (supposedly) been filled
out.

def add_prov():
  ...
  # at this point, the widgets are being created and the user has not
  # had time to enter values yet
  add_proverb = Button(add_frame3, text="Add a Proverb", font=("Arial", 8),
    command=lambda chap=chapter_entry, ver=vers_entry, proverb=add_entry:
      write_prov(chap, ver, proverb)
  )
def write_prov(chap, ver, proverb):
  # get the values after the button has been pressed
  chap = chap.get()
  ver = ver.get()
  proverb = proverb.get()
  ...

Another take on it is to have the button widget destroy the toplevel
widget, and to wait for that to happen.

def add_prov():
  add_window = Toplevel()
  ...
  add_proverb = Button(add_frame3, text="Add a Proverb", font=("Arial", 8),
    command=add_window.destroy)
  add_proverb.pack(side=LEFT, fill=BOTH, expand=1)
  add_window.wait_window()  # wait until destroyed
  write_prov(
    chapter_entry.get(),
    verse_entry.get(),
    add_entry.get()
  )

Or, to create a new event loop for just this (which is how some dialogs
work).

def add_prov():
  add_window = Toplevel()
  ...
  add_proverb = Button(add_frame3, ..., add_window.quit)
  add_proverb.pack(...)
  add_window.mainloop()
  write_prov(...)

Good luck,
  -Arcege

> ---------- Proverb.py ---------------
> from random import randint
> from string import *
> import string
> from Tkinter import *
> 
> def split(proverb):
>         if proverb[-1]=="\012":
>                 proverb=proverb[:-1]
>         else:
>                 proverb=proverb
> 
>         x=len(proverb)/2
> 
>         while proverb[x]!=" ":
>                 x=x+1
>         else:
>                 x=x
> 
>         daily_prov=proverb[:x]+"\n"+"\t"+proverb[x+1:]
>         return daily_prov
> 
> def add_prov():
> 
>         add_window=Toplevel(main)
> 
>         add_frame1=Frame(add_window,relief=SUNKEN,border=0)
>         add_frame1.pack(side=TOP,fill=BOTH)
> 
>         add_frame2=Frame(add_window,relief=SUNKEN,border=0)
>         add_frame2.pack(side=TOP,fill=BOTH)
> 
>         add_frame3=Frame(add_window,relief=SUNKEN,border=0)
>         add_frame3.pack(side=TOP,fill=BOTH)
> 
>         add_entry=Entry(add_frame1,textvariable=typed_entry,fg="black")
>         add_entry.pack(side=LEFT,fill=BOTH,expand=1)
> 
>         chapter_label=Label(add_frame2,text="Chapter")
>         chapter_label.pack(side=LEFT,fill=BOTH)
> 
>         chapter_entry=Entry(add_frame2,textvariable=chap)
>         chapter_entry.pack(side=LEFT,fill=BOTH)
> 
>         verse_label=Label(add_frame2,text="Verse(s)")
>         verse_label.pack(side=LEFT,fill=BOTH)
> 
>         verse_entry=Entry(add_frame2,textvariable=ver)
>         verse_entry.pack(side=LEFT,fill=BOTH)
> 
>         add_proverb=Button(add_frame3,text="Add a
> Proverb",font=("Arial",8),command= lambda
> chap=chapter_entry.get(),ver=verse_entry.get(),proverb=add_entry.get():
> write_prov(chap,ver,proverb))
>         add_proverb.pack(side=LEFT,fill=BOTH,expand=1)
> 
> def write_prov(chapter,verse,proverb):