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