1

On the Forum there has recently been posted a Question by @Clueless_captain; it was answered by @furas. I am new to stackoverflow so I can not comment in that Conversation. This is the URL to that Conversation: (Tkinter Entry widget stays empty in larger programs (Python 2)). The Code posted by furas is not exactly what I try to do, but the only Thing I can not do myself is finding a way to re-use the Input that has been given in the EntryWidget. I modified the Code written by furas; my Goal was that the Input would be printed before the GUI terminated. For that I bound the Return key to a new Function, this Function was supposed to get the Textstring in this new Function where it would further be processed. It does only do that when I click the Button to get a name for a second time. Is the order of this Code off? I believe the Issue is closely related to the String 'e.bind' on line ten, but I can not find the Issue.


Best Regards, G_Lehmann

---------- The modified code:


from Tkinter import *

def get_input(text, variable):
    win = Toplevel()
    win.title("Get value")

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

    e = Entry(win, textvariable=variable)
    e.bind("<Return>", do_more(text, variable, e))
    e.pack(side="right")
    #I tried e.bind here, but This had no Effect.

    b = Button(win, text = "Cancel", command=win.destroy)
    b.pack()
#do_more is the new Function I want to use to process the Variable 'data' further.
def do_more(text, variable, e):
    data = e.get()
    print data
    print len(data)
    print type(data)

def get_value(text, variable):
    get_input(text, variable)

# --- 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 -- (My Edit: I disabled this as I want to bind the Variables before my GUI gets terminated)
"""
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)
"""
Community
  • 1
  • 1
G_Lehmann
  • 13
  • 4
  • Your question is a bit unclear. What is the real problem you are trying to solve? Do you just need to be able to call a function that asks the user to input a string, and you want that function to be configurable (ie: pass in "Your name" or "Your address")? Also, is your real goal just to print the information out, or are the print statements after `mainloop` just for illustrative purposes? Most GUIs shouldn't have any code after `mainloop`. – Bryan Oakley Dec 07 '16 at 20:11
  • `bind` (similar to `command=`) needs function name - it means without `()` and arguments. You can use `lambda` to assign functions with arguments `e.bind("", lambda e:do_more(text, variable, e))` – furas Dec 07 '16 at 20:15
  • BTW: you can create second button - ie. `"OK"` - and assign function to this button and do something before you close window. – furas Dec 07 '16 at 20:19

1 Answers1

0

bind expects function name (like in command=) so you have to use lambda to assign function with arguments. Besides bind execute function with argument event so you have to receive it.

 e.bind("<Return>", lambda event:do_more(variable))

You can assign do_more to button too

b = Button(win, text="OK", command=lambda:do_more(variable))

and do the same with Return and with Button - and close window after do something with variable.

You can also do the same in get_value after you close window but you have to use win.wait_window() because normally tkinter create window and doesn't wait till you close it.

So now you have two possibility to do something with value - in do_more or in get_value - choose one. Both method can be modify - ie. you can use class and create own dialog window.

from Tkinter import *

# --- --- 

# global variable to use in different functions
win = None 

def get_input(text, variable):
    global win # inform function to use global variable `win` to assign value

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

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

    # use `f` instead of `win` to put inside LabelFrame
    e = Entry(f, textvariable=variable)
    e.pack()#side="right")

    e.bind("<Return>", lambda event:do_more(variable))

    b = Button(win, text="OK", command=lambda:do_more(variable))
    b.pack()

def do_more(variable):
    data = variable.get()
    print 'do_more:', data, len(data), type(data)
    win.destroy()

# --- ---

def get_value(text, variable):
    # create window
    get_input(text, variable)

    # this code is executed directly after creating window, not after closing window
    # so code has to wait till window is closed
    win.wait_window()

    data = variable.get()
    print 'get_value:', data, len(data), type(data)

# --- 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()
furas
  • 134,197
  • 12
  • 106
  • 148
  • The print Statement I used was just for Illustration. The real Program would be a Textgame for 9yearolds, probably about Annagrams (The Kids are still thinking over their Class Project). That is the easy Part, and I have learned Python already; but I have never built an Interface and that is taking more Time then I expected... I tried your Code and it is exactly what I wish to do. Thank you for your Time and Explanation. Best Regards G_Lehmann. – G_Lehmann Dec 08 '16 at 10:26