-1

I want to make a program where, after clicking on a button, a user gets asked for its name, after which the program continues. I'm stuck on making the popup return the textstring that has been entered in the popup. At first I thought it was my code, but the I decided to make a second program where it just asks the name, prints it, prints it length and its type. In that second program, everything works as it should. I'm having a very hard time figuring out why it doesn't in the first (larger) program. I've already read (Why is Tkinter Entry's get function returning nothing?) and, even though my .get() function occurs after my .mainloop, it still doesn't work; in that same thread they propose using classes, which is something I know absolutely nothing about. If possible can anyone point out what I'm missing in my larger program?


Large Program


from Tkinter import *

root = Tk()
root.title("Ask-name-SUB")

def getname(usertype):
    getname = Tk()
    getname.title("Get name popup")
    def abort():
        getname.destroy()
    name = StringVar()
    c = LabelFrame(getname, text = "Your name:")
    c.pack()
    d = Entry(getname, textvariable=name)
    d.pack(side="right")
    d.bind("<Return>", lambda event: getname.destroy())
    e = Button(getname, text = "Cancel", command=lambda: abort())
    e.pack()

    getname.mainloop()
    name = (name.get())
    print "Print name, its length, its type"
    print name
    print len(name)
    print type(name)

top = Frame(root)
top.pack(side="top")
bottom = Frame(root)
bottom.pack(side="bottom")
def killit():
    root.destroy()

cancel = Button (bottom, text = "Cancel", command=lambda: killit())
cancel.pack()
askname = Button (top, text = "Enter your name", command=lambda: getname("testuser"))
askname.pack()
root.mainloop()

Small Program


    from Tkinter import *

def getname(usertype):
    getname = Tk()
    getname.title("Get name popup")
    def abort():
        getname.destroy()
    name = StringVar()
    c = LabelFrame(getname, text = "Your name:")
    c.pack()
    d = Entry(getname, textvariable=name)
    d.pack(side="right")
    d.bind("<Return>", lambda event: getname.destroy())
    e = Button(getname, text = "Cancel", command=lambda: abort())
    e.pack()

    getname.mainloop()
    name = (name.get())
    print "Print name, its length, its type"
    print name
    print len(name)
    print type(name)


getname("testuser")
Community
  • 1
  • 1
Clueless_captain
  • 420
  • 2
  • 13
  • larger program doesn't work for me because you mess with name `getname` - you define function `getname` and you use it in widgets because you think you have `getname = Tk()` but it is not true. – furas Dec 03 '16 at 18:00
  • BTW: we use `Tk()` to create only main window. If you need popup/dialog window then use `Toplevel()` – furas Dec 03 '16 at 18:02
  • BTW: probably your large program has wrong indentions - but I think problem is because program should have only one `mainloop()` (and only one `Tk()` as main window) – furas Dec 03 '16 at 18:08
  • Thanks so much Furas, I'll try this in the morning. Can I just ask two small other questions, do I just use 'popupname = Toplevel()' or do I use 'popupname = tk.Toplevel()'. And do I leave the 'mainloop()' out in its entirety, or do I need to replace that by something specific to the 'Toplevel()' (I can't find this in the Tkinter documentation). Sorry about the indentation. When pasting my code in stackoverflow I lost all indents and forgot to fix that. - I'll edit it right away. – Clueless_captain Dec 03 '16 at 18:42
  • if you already use `from Tkinter import *` then you have to use `Toplevel()` without `tk.` But if you use only `import Tkinter as tk` then you will have to use `tk.Toplevel()` but also `tk.Tk()` and `tk.Label()`, `tk.Button()`, etc. It need more changes in code but it can be more readable because you can use normal `tk.Button()` and themed version `ttk.Button()` and own class `Button()`. – furas Dec 03 '16 at 18:50
  • keep `root.mainloop()` in current place - don't use it in inside functions ie. `popupname.mainloop()`. – furas Dec 03 '16 at 18:52

1 Answers1

0

I can't run your large program - probably you have wrong indentions.

I see two problems:

  • program should have only one mainloop() - and it can be your problem.
  • we use Tk() to create main window, and Toplevel() to create other windows.

Besides you use name getname as function name and as second window instance so it is very misleading.

I create global var_name to keep name and later I use it inside function.

from Tkinter import *

def get_name(usertype):

    win = Toplevel()
    win.title("Get name popup")

    f = LabelFrame(win, text = "Your name:")
    f.pack()

    # use global `name` which was created outside function
    e = Entry(win, textvariable=var_name)
    e.pack(side="right")
    e.bind("<Return>", lambda event: win.destroy())

    b = Button(win, text = "Cancel", command=win.destroy)
    b.pack()

# --- main --

root = Tk()
root.title("Ask-name-SUB")

# global variable
var_name = StringVar()

b = Button(root, text="Enter your name", command=lambda: get_name("testuser"))
b.pack()

b = Button(root, text="Cancel", command=root.destroy)
b.pack()

root.mainloop()

# --- after --
name = var_name.get()
print "Print name, its length, its type"
print name, len(name), type(name)

EDIT:

To makes popup window more universal you can use arguments - displayed text and variable for result.

def get_value(text, variable):

and then you can use it with different text and different variable - ie. for name or for address.

from Tkinter import *

def get_value(text, variable):

    win = Toplevel()
    win.title("Get value")

    f = LabelFrame(win, text=text)
    f.pack()

    e = Entry(win, textvariable=variable)
    e.pack(side="right")
    e.bind("<Return>", lambda event: win.destroy())

    b = Button(win, text = "Cancel", command=win.destroy)
    b.pack()

# --- main --

root = Tk()
root.title("Ask-name-SUB")

# global variables
var_name = StringVar()
var_address = StringVar()

b = Button(root, text="Enter your name", command=lambda: get_value("Your name:", var_name))
b.pack()

b = Button(root, text="Enter your address", command=lambda: get_value("Your address:", var_address))
b.pack()

b = Button(root, text="Cancel", command=root.destroy)
b.pack()

root.mainloop()

# --- after --

name = var_name.get()
print "Print name, its length, its type"
print name, len(name), type(name)

address = var_address.get()
print "Print address, its length, its type"
print address, len(address), type(address)
furas
  • 134,197
  • 12
  • 106
  • 148