Python: как я могу получить значение Entry в функции - PullRequest
1 голос
/ 28 марта 2020

Я новичок в python и создаю интерфейс, в котором я могу нажать на кнопку, чтобы открыть новое окно, а затем заполнить форму.

Моя проблема заключается в том, чтобы получить значение записи после того, как клиент нажал кнопку печати. Сначала, как вы можете видеть, я создал окно. Это пример того, что я хочу сделать.

def return_nom(*args):
    return ent1.get()


def save():
    print("your name is", return_nom())


def new_win():
    top = Toplevel(fen)
    top.title("new window")
    strvar = StringVar()
    strvar.trace("w", return_nom)
    ent1 = Entry(top, textvariable=strvar)
    bouton1 = Button(top, text='print', command=save)
    bouton1.pack()
    ent1.pack()
    top.mainloop()


fen = Tk()
lab = Label(fen)
lab.pack()
bouton = Button(fen, text='new window', command=new_win)
bouton.pack()
fen.mainloop()

Если кто-то может сказать мне, почему он не работает, и объяснить, почему этот метод работает, когда я использую его для входа в основной интерфейс. Спасибо всем ! ;)

Ответы [ 2 ]

1 голос
/ 28 марта 2020

Основная проблема, с которой вы столкнулись, это 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, которым вы можете следовать получить более глубокие знания этой библиотеки инструментария.

0 голосов
/ 28 марта 2020

Проверьте, что говорит трассировка, когда вы начинаете печатать:

Exception in Tkinter callback
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/tkinter/__init__.py", line 1883, in __call__
    return self.func(*args)
  File "tktest.py", line 3, in return_nom
    return ent1.get()
NameError: name 'ent1' is not defined

Когда вы определяете переменную в функции, она не определяется автоматически в других функциях. Это называется «область видимости переменной». Либо вы определяете ent1 в функции new_win () с помощью ключевого слова global, либо вы делаете его атрибутом функции:

new_win.ent1 = Entry(top, textvariable=strvar)
...
new_win.ent1.pack()

и вызываете его так:

def return_nom(*args):
    return new_win.ent1.get()

Удачного программирования!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...