python - tkinter TopLevel 销毁引发 AttrbuteError
问题描述
我正在 tkinter 中编写一个多窗口 GUI。单击主窗口中的“加载 CSV 数据”按钮会创建一个 LoadWindow 类的实例,该实例继承自tkinter.TopLevel
,并且 MainGui 实例被传递给 LoadWindow,因为我想从 LoadWindow 操作它。但是,当我self.destroy
在单击“加载 CSV”按钮时调用关闭“加载 CSV”窗口时,即使“加载 CSV 数据”窗口关闭,我也会收到以下错误。
if self._name in self.master.children:
AttributeError: 'MainGUI' object has no attribute 'children'
下面是代码:
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox
import os
import pandas as pd
class MainGUI:
def __init__(self, master):
self.master = master
master.title("Main Window")
master.geometry("700x500")
# create all elements in main window
load_csv_button = ttk.Button(master,
text='Load CSV Data',
command=lambda: LoadWindow(master=self))
load_db_button = ttk.Button(master, text='Load from Database')
save_db_button = ttk.Button(master, text='Save Current File to Database')
data_transform_button = ttk.Button(master, text='Data Transformation')
data_analysis_button = ttk.Button(master, text='Data Analysis')
#update later
preview_df_button = ttk.Button(master, text='Preview Data Frame',
command=lambda: print(self.main_df))
self.text_box = tk.Text(master, bg='grey')
# insert welcome message into text box and disable
self.text_box.insert(tk.END, 'Welcome to the Data Analysis Hub')
self.text_box.config(state='disabled')
# snap all elements to grid
load_csv_button.grid(row=0, column=1, sticky='NSEW')
load_db_button.grid(row=1, column=1, sticky='NSEW')
save_db_button.grid(row=2, column=1, sticky='NSEW')
data_transform_button.grid(row=0, column=2, sticky='NSEW')
data_analysis_button.grid(row=1, column=2, sticky='NSEW')
preview_df_button.grid(row=2, column=2, sticky='NSEW')
self.text_box.grid(row=4, column=1, columnspan=2)
self.main_df = None
def update_textbox(self, message):
self.text_box.config(state='normal')
self.text_box.delete('1.0', 'end')
self.text_box.insert(tk.END, message)
self.text_box.config(state='disabled')
class LoadWindow(tk.Toplevel):
def __init__(self, master):
tk.Toplevel.__init__(self)
self.title("Load CSV")
self.geometry("200x200")
self.master = master
# get csvs in current directory
listbox = tk.Listbox(self, selectmode=tk.SINGLE)
csv_files = self.find_csv_files(os.getcwd())
for csv in csv_files:
listbox.insert(tk.END, csv)
listbox.grid(row=1, column=1, columnspan=3, sticky='NSEW')
# assign selected csv to maindf
active = listbox.get(tk.ACTIVE)
load_csv_button = ttk.Button(self, text='Load CSV',
command=lambda: self.load_selected(active))
load_csv_button.grid(row=2, column=1)
def find_csv_files(self, path):
# Check for csvs in path
filenames = os.listdir(path)
csv_files = [x for x in filenames if x.endswith('.csv')]
return csv_files
def load_selected(self, active):
try:
csv_path = os.getcwd()+"/"+active
main_df = pd.read_csv(csv_path)
# update maingui variable
self.master.main_df = main_df
# update maingui status on df loaded
self.master.update_textbox(f'{active} loaded as DataFrame')
self.destroy()
except pd.errors.ParserError:
error = 'Looks like you either have no csvs in working directory ' \
'or loaded a file that is not a csv, please try another file'
messagebox.showerror(title='Load error', message=error)
if __name__ == '__main__':
window = tk.Tk()
maingui = MainGUI(window)
window.mainloop()
解决方案
从这一行开始:
LoadWindow(master=self)
self
不是窗口。在__init__
你做的里面self.master = master
。因此,self.master
inside ofLoadWindow
不是小部件,因此它没有children
属性。
您需要将创建方式更改LoadWindow
为如下所示:
LoadWindow(master=self.master)
推荐阅读
- css - 在灰度背景图像上将文本颜色从黑色“反转”为白色
- python - Python networkx边缘和节点标记问题
- java - 无法使用 java 中的 openchannel 访问远程机器中的 cmd 提示符
- python - 使用 np.repeat 将一维数组扩展为多维数组
- javascript - 谁能教我下面给出的这个JS代码?
- javascript - 循环遍历数组以使用 vanilla javascript 创建图像滑块
- r - 如何为 R 包创建 Datavisual 形状
- python - Python Bokeh 绘图工具 - 更改代码的字体大小(X 和 Y 轴)
- vue.js - v-currency 如何从模型值中删除符号?
- authentication - 为单个 repo 作曲家多重身份验证