Основная проблема, с которой вы столкнулись, это scope , так как вы пытаетесь получить доступ к Entry и StringVar из функций, которые к нему не имеют доступа.
Имя ent1
определено внутри new_win()
не будет доступно из return_nom()
.
Более того, мне кажется, что вы на самом деле хотите запрашивать это StringVar, а не сам виджет Entry.
Как передать StringVar вызываемым функциям, существует несколько способов:
- Сделать глобальную переменную
strvar
таким образом, чтобы другие функции имели к ней доступ. Вероятно, это худшее из возможных решений этой проблемы, поскольку смысл наличия функций состоит в том, чтобы избежать загрязнения пространства имен глобального пространства имен. - Сделать функции
return_nom()
и save()
внутренними функциями new_win()
, что позволяет им получить доступ к локальным переменным в new_win()
как замыкание. Это немного лучше. - Используйте объектно-ориентированный интерфейс, где ваш StringVar является элементом экземпляра, а ваш
save()
является методом. Такое состояние, как StringVar, доступно для всего экземпляра. Это, вероятно, лучший вариант, именно так Tkinter действительно предназначен для использования, он наиболее естественно соответствует объектно-ориентированному подходу.
Пример использования внутренних функций:
def new_win():
top = Toplevel(fen)
top.title("new window")
strvar = StringVar()
def return_nom(*args):
return strvar.get()
def save():
print("your name is", return_nom())
ent1 = Entry(top, textvariable=strvar)
bouton1 = Button(top, text='print', command=save)
bouton1.pack()
ent1.pack()
top.mainloop()
Примером объектно-ориентированного подхода может быть:
class MyDialog:
def __init__(self, fen):
self.fen = fen
self.strvar = StringVar()
def return_nom(self, *args):
return self.strvar.get()
def save():
print("your name is", self.return_nom())
def new_win(self):
top = Toplevel(self.fen)
top.title("new window")
ent1 = Entry(top, textvariable=self.strvar)
bouton1 = Button(top, text='print', command=self.save)
bouton1.pack()
ent1.pack()
top.mainloop()
А затем на верхнем уровне:
my_dialog = MyDialog(fen)
bouton = Button(fen, text='new window', command=my_dialog.new_win)
Но вышеприведенное все еще не лучший подход который фактически должен был бы создать подклассы Tkinter.Frame
для вашего windows, соединить их вместе с помощью методов, и ваш код верхнего уровня только создает экземпляр основного класса Application и вызывает для него app.mainloop()
, позволяя ему управлять всем приложением проходить через события, связанные с методами и другими фреймами.
См. простую программу Hello World в документации Python tkinter в стандартной библиотеке Python, чтобы получить несколько лучшее представление о том, как tkinter предназначен для использования.
Эта документация также содержит ссылки на многие другие ресурсы по tkinter и по самой Tk, которым вы можете следовать получить более глубокие знания этой библиотеки инструментария.