Обращение к объекту класса из класса в другом файле
Подскажите, пожалуйста, как сделать чтобы при нажатии кнопки btn1
окно toplevel
закрывается и при этом мне нужно чтобы title_info
изменил текст на var
из класса Top()
, который в другом файле?
main.py:
import customtkinter
import test2 as t2
class Frame(customtkinter.CTkFrame):
def __init__(self, master):
super().__init__(master)
self.put_widget()
def action_btn_signin(self):
# +++
# main.title_info.configure(text="Open Toplevel") # +++
t2.Top()
def put_widget(self):
self.btn = customtkinter.CTkButton(self, text="open toplevel", command=self.action_btn_signin)
self.btn.grid(row=1, column=0, padx=20, pady=(10, 10), sticky="ew")
class Main(customtkinter.CTk):
def __init__(self):
super().__init__()
self.put_widget()
def put_widget(self):
self.title_info = customtkinter.CTkLabel(self, text="Docs")
self.title_info.grid(row=0, column=0, padx=10, pady=10)
self.info_frame = Frame(self)
self.info_frame.configure(corner_radius=14)
self.info_frame.grid(row=1, column=0, padx=(20, 5), pady=(20, 5))
if __name__ == "__main__":
main = Main()
main.mainloop()
Когда все классы в одном файле, то все работает, но стоит резнести по фалам то выдает ошибку, что "у класса такого атрибута нет"
test2.py
import customtkinter
import test
class Top(customtkinter.CTkToplevel):
def __init__(self):
super().__init__()
self.put_widget()
self.var = "main_window"
def pass_to_main(self):
# Main.Main.title_info.configure(text=self.var)
# !!! +++
test.title_info.configure(text=self.var) # title_info изменил текст на var
self.destroy() # +++ окно toplevel закрывается
def put_widget(self):
self.btn1 = customtkinter.CTkButton(self, width=200, text="push", corner_radius=24, font=("Arial", 18), command=self.pass_to_main)
self.btn1.grid(row=0, column=0, padx=20, pady=(20, 10), ipady=10, sticky="ewn")
Ответы (2 шт):
Автор решения: insolor
→ Ссылка
- Вы обращаетесь к
test.title_info
, но у васtest
- это модуль, а не основное окно. У модуляtest
действительно нет атрибутаtitle_info
- У вас тут циклический импорт - файлы друг друга импортируют, так делать не нужно.
- В идеале дочернее окно вообще не должно ничего знать про родительское (не должно пытаться писать в него какие-то значения), а должно просто возвращать результат. Примерный код как это можно реализовать:
import tkinter as tk
class Child(tk.Toplevel):
def __init__(self):
super().__init__()
self.entry = tk.Entry(self)
self.entry.pack()
self.value = None # По умолчанию результат None
self.button_ok = tk.Button(self, text="OK", command=self.ok)
self.button_ok.pack()
def ok(self):
# Записываем результат в атрибут объекта, потом закрываем окно
self.value = self.entry.get()
self.destroy()
def wait_result(self):
self.wait_window() # Ждем закрытия окна
return self.value # Возвращаем результат
class Main(tk.Tk):
def __init__(self):
super().__init__()
self.button = tk.Button(self, text="Вызвать дочернее окно", command=self.show_child_window)
self.button.pack()
self.result_label = tk.Label(self, text="Тут будет результат")
self.result_label.pack()
def show_child_window(self):
child = Child()
# Ждем результат из дочернего окна, потом отображаем его в метке
self.result_label.config(text=child.wait_result())
if __name__ == "__main__":
app = Main()
app.mainloop()
Автор решения: S. Nick
→ Ссылка
Попробуйте так:
main.py:
import customtkinter
#import test2 as t2
# !!! +++
from q1580033_test2 import Top # !!! +++
class Frame(customtkinter.CTkFrame):
def __init__(self, master):
super().__init__(master)
# !!! +++
self.master = master # !!! +++
self.put_widget()
def action_btn_signin(self):
# +++ vvvvvvvvvvv <----------------------------------------------------
self.master.title_info.configure(text="Open Toplevel") # +++
# t2.Top()
Top(self.master) # !!! +++
def put_widget(self):
self.btn = customtkinter.CTkButton(self,
text="open toplevel", command=self.action_btn_signin)
self.btn.grid(row=1, column=0,
padx=20, pady=(10, 10), sticky="ew")
class Main(customtkinter.CTk):
def __init__(self):
super().__init__()
self.put_widget()
def put_widget(self):
self.title_info = customtkinter.CTkLabel(self, text="Docs")
self.title_info.grid(row=0, column=0, padx=10, pady=10)
self.info_frame = Frame(self)
self.info_frame.configure(corner_radius=14)
self.info_frame.grid(row=1, column=0, padx=(20, 5), pady=(20, 5))
if __name__ == "__main__":
main = Main()
main.mainloop()
q1580033_test2.py:
import customtkinter
#import test
class Top(customtkinter.CTkToplevel):
# +++ --------------> vvvvvv <----------------------------------------------
def __init__(self, master): # !!! +++
super().__init__()
self.master = master # !!! +++
self.put_widget()
self.var = "main_window"
def pass_to_main(self):
# Main.Main.title_info.configure(text=self.var)
# !!! +++
# test.title_info.configure(text=self.var)
# +++ vvvvvvvvvvv <--------------------------------------------------------
self.master.title_info.configure(text=self.var) # !!! +++
self.destroy() # +++ окно toplevel закрывается
def put_widget(self):
self.btn1 = customtkinter.CTkButton(self,
width=200, text="push", corner_radius=24,
font=("Arial", 18), command=self.pass_to_main)
self.btn1.grid(row=0, column=0, padx=20, pady=(20, 10),
ipady=10, sticky="ewn")