问题
I've written a very simple code with python tkinter
, it contains an input box. I'd like to keep the value inserted by the user to myself, in case I need to use it later.
Here's the code:
import tkinter as tk
root=tk.Tk()
root.geometry("600x400")
def submit():
name=name_entry.get()
return name
name_label = tk.Label(root, text = 'Username',
font=('calibre',
10, 'bold'))
name_entry = tk.Entry(root,
font=('calibre',10,'normal'))
sub_btn=tk.Button(root,text = 'Submit',
command = submit)
name_label.grid(row=0,column=0)
name_entry.grid(row=0,column=1)
sub_btn.grid(row=2,column=1)
root.mainloop()
In function submit
I've written return name
, in order to return the inserted name of the user. But how can I access it outside of the function? I want to keep the value somewhere, but I don't know how to.
I appreciate your kind help in advance
回答1:
Most times, callbacks drop the return value (all tkinter
callbacks do), if any. This is because is is a bit awkward to manage return values using the observer pattern which is most often used for callbacks.
There are two main ways to transfer a value from the CB to where it is needed:
One is to use a container object
- that may be a simple python list
or dict
, or a more elaborate data class
that is accessible by the callback
, and mutated to assign the proper values to it.
here is a very simple example using a dictionary:
import tkinter as tk
def print_info():
print(f'from print_info: {information_transfer}')
def submit():
information_transfer['name'] = name_entry.get()
print(f'after input: {information_transfer}')
root=tk.Tk()
root.geometry("600x400")
name_label = tk.Label(root, text = 'Username', font=('calibre', 10, 'bold'))
name_entry = tk.Entry(root, font=('calibre', 10, 'normal'))
sub_btn = tk.Button(root,text='Submit', command=submit)
info_btn = tk.Button(root,text='print info', command=print_info)
name_label.grid(row=0, column=0)
name_entry.grid(row=0, column=1)
sub_btn.grid(row=2, column=1)
info_btn.grid(row=3, column=1)
information_transfer = {'name': None, 'other': None}
print(f'before input: {information_transfer}')
root.mainloop()
Another is the OOP approach described by @DavidGildour in another answer.
回答2:
I would recommend using OOP approach, to have an object retaining a state:
import tkinter as tk
class Program:
def __init__(self):
self.root = tk.Tk()
self.name_label = tk.Label(self.root, text='Username',
font=('calibre', 10, 'bold'))
self.name_entry = tk.Entry(self.root, font=('calibre', 10, 'normal'))
self.sub_btn = tk.Button(self.root, text='Submit', command=self.submit)
self.submitted_var = tk.StringVar()
self.submitted_label = tk.Label(self.root, text="Submitted name: ")
self.submitted_entry = tk.Label(self.root, textvariable=self.submitted_var)
def setup(self):
self.submitted_label.grid(row=0, column=0)
self.submitted_entry.grid(row=0, column=1)
self.name_label.grid(row=1, column=0)
self.name_entry.grid(row=1, column=1)
self.sub_btn.grid(row=2, column=1)
def submit(self):
self.submitted_var.set(self.name_entry.get())
def run(self):
self.setup()
self.root.mainloop()
if __name__ == '__main__':
Program().run()
Then you can use self.submitted_var.get()
anywhere to get the last submitted value. Although, the more straight-forward way would be to link a StringVar
directly to name_entry
, but then it would change every time the Entry
widget value changes, rendering the submit button useless.
来源:https://stackoverflow.com/questions/64696223/how-to-return-a-value-of-a-function-given-as-a-command-in-tkinter