#python #tkinter
#python #tkinter
Вопрос:
Я создаю приложение с графическим интерфейсом в Tkinter и структурировал свою программу, используя ООП-подход. Я создал tk.Экземпляр Tk() и класс, который наследуется от tk.Фрейм принимает экземпляр Tk () в качестве параметра, и я создаю графический интерфейс и логику, стоящую за ним, внутри класса.
Внутри класса я создал холст, на котором я разместил несколько виджетов. Один из моих виджетов — это запись, а другой — кнопка. Команда кнопки должна быть функцией, которая принимает в качестве входного параметра текущее значение записи (используя метод Entry.get()) и что-то с этим делает, скажем, выводит это на экран.
Это некоторый код, в котором я воссоздал проблему:
import tkinter as tk
class myClass(tk.Frame):
def __init__(self, master):
super(myClass, self).__init__(master)
self.pack()
self.Widgets()
def getVal(self, val):
print("The value is: ", val)
def Widgets(self):
canvas = tk.Canvas(self, width=500, height=500, bg='green')
canvas.grid(row=0, column=0)
entry = tk.Entry()
button = tk.Button(text='pressme')
button['command'] = lambda arg = entry.get() : self.getVal(arg)
window = canvas.create_window(100, 100, window=entry)
window2 = canvas.create_window(100, 200, window=button)
root = tk.Tk()
root.title("MyGUI")
classinstance = myClass(root)
root.mainloop()
Функция ‘getVal’ из класса должна выводить любое значение аргумента, где должно быть текущее значение из записи графического интерфейса. Проблема в том, что моя программа видит только начальное значение из этой записи (которое в данном случае является пустой строкой) и не изменяет его впоследствии, когда я обновляю графический интерфейс во время выполнения.
Теперь я предполагаю, что это связано с тем, что в программе main.py classinstance создается с некоторыми значениями по умолчанию перед тем, как приложение войдет в функцию mainloop() tkinter, и после выполнения этой функции цикла я не могу вернуться внутрь класса и изменить значения. Пожалуйста, помогите мне исправить эту проблему и объясните мне, как я мог бы сделать свое приложение таким, чтобы команда кнопки получала обновленную версию значения записи, а не первоначальную. Спасибо, что прочитали мой пост!
Комментарии:
1. Есть ли причина, по которой вы написали
lambda arg = entry.get() : self.getVal(arg)
вместоlambda: self.getVal(entry.get())
? Что натолкнуло вас на мысль, что там необходим аргумент по умолчанию?2. Я хотел сделать код более понятным: D. Я думаю, я понимаю, в чем была проблема. Лямбда-функция всегда использовала исходное значение ‘arg’. Спасибо. Как я могу принять ваше решение?
3. Вы не можете. Вы можете написать и принять свой собственный ответ, если хотите.
Ответ №1:
Как указал @Aran-Fey, лямбда-функция всегда использовала исходное значение ‘arg’ и не меняла его. Для того, чтобы это сработало, следует использовать метод entry.get(), а не аргумент по умолчанию:
lambda: self.getVal(entry.get())
Ответ №2:
Ошибка была обнаружена в функции кнопки, потому что lambda arg = entry.get()
импортируется arg
только при создании кнопки. Затем, когда кнопка нажата, лямбда-выражение передает в функцию значение arg
, полученное в начале, без его повторного импорта.
import tkinter as tk
class myClass(tk.Frame):
def __init__(self, master):
super(myClass, self).__init__(master)
self.pack()
self.Widgets()
def getVal(self, val):
print("The value is: ", val)
def Widgets(self):
canvas = tk.Canvas(self, width=500, height=500, bg='green')
canvas.grid(row=0, column=0)
var = tk.StringVar()
entry = tk.Entry(textvariable = var)
button = tk.Button(text='pressme')
button['command'] = lambda: self.getVal(var.get())
window = canvas.create_window(100, 100, window=entry)
window2 = canvas.create_window(100, 200, window=button)
root = tk.Tk()
root.title("MyGUI")
classinstance = myClass(root)
root.mainloop()