#python #python-3.x #tkinter #return-value #tkinter-entry
#python #python-3.x #tkinter #возвращаемое значение #tkinter-запись
Вопрос:
Я написал очень простой код на python tkinter
, он содержит поле ввода. Я бы хотел сохранить значение, введенное пользователем, для себя, на случай, если мне понадобится использовать его позже.
Вот код:
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()
В функции submit
, которую я написал return name
, чтобы вернуть вставленное имя пользователя. Но как я могу получить к нему доступ за пределами функции? Я хочу сохранить значение где-нибудь, но я не знаю, как это сделать.
Я заранее ценю вашу любезную помощь
Комментарии:
1. Простой способ — использовать глобальную переменную для хранения значения. Поэтому добавьте
global name
в началеsubmit()
.
Ответ №1:
В большинстве случаев обратные вызовы отбрасывают возвращаемое значение (все tkinter
обратные вызовы делают), если таковые имеются. Это связано с тем, что немного неудобно управлять возвращаемыми значениями с использованием шаблона observer, который чаще всего используется для обратных вызовов.
Существует два основных способа передачи значения из CB туда, где оно необходимо:
Один из них заключается в использовании container object
— , который может быть простым python list
или dict
, или более сложным data class
, доступным с помощью callback
, и измененным для присвоения ему правильных значений.
вот очень простой пример использования словаря:
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()
Другим является подход ООП, описанный @DavidGildour в другом ответе.
Комментарии:
1. Запустив ваш код, я получаю сообщение об ошибке
name is not defined
2. Да, конечно, извините — ключи dict должны быть строками; Я исправил опечатку.
3. ну, теперь я не получаю никаких ошибок, но печать
information_transfer[name]
показывает мнеNone
, поэтому кажется, что у меня все еще нет доступа к пользовательскому вводу.4. Пожалуйста, я добавил
print_info
функцию и кнопку, которая ее вызывает, для вашего удобства.5. Не «большинство» раз. Обратные вызовы всегда отбрасывают возвращаемое значение.
Ответ №2:
Я бы рекомендовал использовать подход ООП, чтобы объект сохранял состояние:
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()
Затем вы можете использовать self.submitted_var.get()
anywhere для получения последнего отправленного значения. Хотя более простым способом было бы связать a StringVar
напрямую с name_entry
, но тогда оно будет меняться каждый раз Entry
, когда изменяется значение виджета, что делает кнопку отправки бесполезной.