#python #tkinter #jupyter
#python #tkinter #jupyter
Вопрос:
Я хочу изменить текст в окне состояния, когда пользователь нажимает кнопку. Текущее состояние при запуске страницы — «файл не загружен», после нажатия кнопки я бы хотел, чтобы текст на этой кнопке изменился, чтобы показать, что «файл загружен» или что-то подобное.
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text="Load Data from Files", font=controller.title_font)
label.pack(side="top", fill="x", pady=10)
invButton = tk.Button(self, text="Load Inventory Data", command = self.openFile)
invButton.pack()
invStatusText = tk.StringVar()
invStatusText.set("No file selected")
invStatus = tk.Button(self, state='disabled')
invStatus.config(textvariable=invStatusText)
invStatus.pack()
def openFile(self):
name = fd.askopenfilename()
self.invStatusText.set("File Loaded")
Когда я запустил это, не передавая self в OpenFile(), и он срабатывает при вводе функции OpenFile с сообщением NameError: name 'invStatusText' is not defined
. Я стал ближе при использовании self (приведенный выше код). В этом случае я получаю следующее:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:anaconda3libtkinter__init__.py", line 1883, in __call__
return self.func(*args)
File "<ipython-input-6-99355e7afb55>", line 84, in openFile1
self.invStatusText.set("File Loaded")
AttributeError: 'PageOne' object has no attribute 'invStatusText'
Итак, я хотел бы изменить текст кнопки invButton, изменив значение переменной, хранящейся в __init__
функции, но это мне не позволяет. Я видел в другом месте (у меня открыто около 20 вкладок StackOverflow), что эти переменные должны быть определены на уровне класса, за пределами __init__
, но когда я попытался поместить invStatusText внутри класса, я получил сообщение AttributeError: 'NoneType' object has no attribute '_root'
Ответ №1:
В __init__
вам нужно сделать атрибут, который вы хотите вызвать, атрибутом экземпляра (добавив к нему self):
class PageOne(tk.Frame):
def __init__(self, parent, controller):
...
self.invStatusText.set("No file selected")
...
def openFile(self):
name = fd.askopenfilename()
self.invStatusText.set("File Loaded")
Также я хотел бы отметить, что обычно вы не должны что-то делать __init__
. Создайте отдельный метод для создания пользовательского интерфейса, а не делайте это там. По мере роста вашего пользовательского __init__
интерфейса ваш станет непонятным.
Комментарии:
1. Спасибо, это было все, и я буду использовать совет о создании метода createUI для выполнения всего этого типа вещей, очень признателен.