Использование .get() для извлечения переменной Tkinter из другого класса

#python #tkinter

#python #tkinter

Вопрос:

Я пишу приложение Tkinter, которое требует, чтобы части пользовательского дисплея существовали в двух разных классах, оба импортированных из другого файла. Мне нужно взять часть пользовательского ввода и передать ее из одного класса в другой. В приведенном ниже примере с игрушкой пользователь должен ввести что-то, my_entry_input к чему позже класс PullVariable должен получить доступ.

Код приведен ниже. У меня было несколько мыслей, например, как каким-то образом использовать глобальные переменные или создать функцию в исходном классе, чтобы получить переменные, а затем передать их обратно. Во всех случаях я получаю:

Ошибка атрибута: объект типа «Приложение» не имеет атрибута «my_entry»

Лучшее решение, которое я могу придумать, — это создать функцию, которая отвечает на привязку, а затем передать .get() другому классу из этой функции. Мне кажется, что tkinter не нравится .get() между классами.

Спасибо сообществу за вашу помощь.

Главная

 from import_test1 import *

root=Tk()
ui = Application(root)
ui.hello_world()
ui.entry()

pv = PullVariable()

if __name__ == '__main__':
    root.mainloop()
  

ИМПОРТИРОВАННЫЙ КОД

 from tkinter import *
from tkinter import ttk

class Application(Frame):        
    def __init__(self, parent, *args, **kwargs):
        print('Application init')
        Frame.__init__(self, parent, *args, **kwargs)
        self.parent=parent
        self.parent.grid()

    def entry(self):
        self.my_entry = StringVar(self.parent)
        my_entry_input = Entry(self.parent, textvariable=self.my_entry, 
            width=16)
        my_entry_input.bind('<FocusOut>', self.show_entry)
        my_entry_input.grid(column=0, row=1)
        self.show_label = Label(self.parent, text = '')
        self.show_label.grid(column=0, row=2)

    def hello_world(self):
        print('hello world')
        self.hw = Label(self.parent, text='Hello World!')
        self.hw.grid(column=0, row=0)

    def show_entry(self, event):
        PullVariable(Application).find_entry()

class PullVariable:
    def __init__(self, app):
        self.app = app
        print('Pull initiated')

    def find_entry(self, event=None):
        self.pulled_entry = self.app.my_entry.get()
        self.app.show_label['text'] = self.pulled_entry

  

Ответ №1:

my_entry не является атрибутом Application класса, поэтому вы не можете сделать Application.my_entry , это атрибут экземпляра Application класса, поэтому вы можете сделать Application().my_entry . Вероятно, вы можете добавить либо экземпляр Application , либо my_entry к __init__ методу PullVariable . Я буду использовать первое.

 # ...
class PullVariable:
    def __init__(self, app): # add app here
        self.pulled_entry = app.my_entry.get() # use app here
        print(self.pulled_entry)
# and then
root=Tk()
ui = Application(root)
ui.hello_world()
ui.entry()

pv = PullVariable(ui) # supply PullVariable with instance of Application
  

Комментарии:

1. Многообещающий… могу ли я передать app в другую функцию внутри PullVariable класса?

2. Если вы подключаетесь app к экземпляру внутри __init__ . Итак self.app = app . Я бы рекомендовал изучить основы ООП на Python, прежде чем пытаться писать tkinter приложение.

3. Не уверен, что ваша снисходительность оправдана. Я специалист, но я не новичок в ООП. Я просто пытаюсь узнать об импорте нескольких классов и о том, как я могу заставить их взаимодействовать. Вы здесь новичок, поэтому я не буду вас принижать, но я не думаю, что это правильный способ вести себя. Кроме того, ваша идея кода не работает. Если я делаю что-то вроде вызова функции внутри класса PullVariable после привязки, он хочет повторно инициализировать класс, что не сработает.

4. Извините, я не уверен, что правильно понял ваш вопрос. Не могли бы вы рассказать, чего вы пытаетесь достичь, возможно, с помощью какого-нибудь более практического примера? Вы просто хотите иметь два класса, чтобы иметь ссылку на один объект? Что вы имеете в виду под повторной инициализацией класса? Почему вы не можете просто передать ссылку на конструкторы / методы?