【问题标题】:Tkinter Window Closing Automatically after one runTkinter 窗口在一次运行后自动关闭
【发布时间】:2020-08-23 14:06:10
【问题描述】:

所以我正在编写一个界面,它将自动执行一些步骤数据分析。该代码涉及将用于不同功能的多个屏幕。我写的第一个是EDA(探索性数据分析)屏幕。该代码有效,但会生成报告,然后关闭 Tk 窗口。

具体来说,当我生成报告时,代码会生成报告然后关闭。我没有将代码生成放在那里,因为它不使用 Tkinter。还省略了其他屏幕,因为它们没有问题,我不想在这里转储整个项目。

import HTMLCreator as sv
from tkinter import *
import tkinter.filedialog
import time
import pandas as pd
import Credentials as cred
import os
class EDAScreen(Page):
   
    def __init__(self, *args, **kwargs):

        Page.__init__(self, *args, **kwargs)
        self.fields = ['First X Column Name', 'Last X Column Name', 'First Y Column name','Last Y Column Name']
        self.entries = []
        self.df=""
        self.things=[]
        self.description = "Automate EDA for a Dataset"
        self.instructions = "Upload the CSV file with all the data"

        self.descriptionLabel = Label(self, text = self.description, font=("System", 13)).place(x = 140, y = 150)
        self.instructionsLabel = Label(self, text = self.instructions, font=("System", 13)).place(x = 190, y =180)
        self.genResultButton = Button(self, text = "Upload input file", font=("Arial", 18), command = self.open).place(x = 290, y = 230)
        self.edaButton=Button(self, text = "Generate Report", font=("Arial", 18), command = self.EDA).place(x = 290, y = 330)
       
        # root.config(background='gray')
        for ndex, field in enumerate(self.fields):
            Label(self, width=20, text=field, anchor='w').grid(row=ndex, column=0, sticky='ew')
            self.entries.append(Entry(self))
            self.entries[-1].grid(row=ndex, column=1, sticky='ew')


        Button(self, text='Set these Params', command=self.fetch).grid(row=len(self.fields)+1, column=1, sticky='ew')

    def fetch(self):
        for ndex, entry in enumerate(self.entries):
            print('{}: {}'.format(self.fields[ndex], entry.get()))
            self.things.append(entry.get())
    
    def EDA(self):
        sv.createHTML(self.df,self.things[:2],self.things[2:])

    
    # Get the prediction answer by searching for file
    def open(self):
        filename =  tkinter.filedialog.askopenfilename(parent=self,initialdir = "./",title = "Select file",filetypes = (("data files","*.csv"),("all files","*.*")))
        print(filename)
        self.df=pd.read_csv(filename)
        cols=self.df.columns.values
        print(cols)
        try:  
            os.mkdir("./Breakdowns")
        except :
            pass
        # print("Things: ",things)
       
        #iv.processImg(r,'jpg')

当您没有主循环时,这似乎是一个问题。然而,我确实有一个定义为:

if __name__ == "__main__":
    root = Toplevel()
    root.geometry("800x500")
    main = MainView(root)
    main.pack(side="top", fill="both", expand=True)
    root.mainloop()

其他重要的定义是

class Page(Frame):

    def __init__(self, *args, **kwargs):
        Frame.__init__(self, *args, **kwargs)

    def show(self):
        self.lift()


class MainView(Frame):

    def __init__(self, *args, **kwargs):
        
        Frame.__init__(self, *args, **kwargs)
        
        introScreen = IntroScreen(self)
        edaScreen = EDAScreen(self)

        buttonFrame = Frame(self)
        container = Frame(self)
        buttonFrame.pack(side="top", fill="x", expand=False)
        container.pack(side="top", fill="both", expand=True)

        edaScreen.place(in_ = container, x = 0, y = 0, relwidth = 1, relheight = 1)
        introScreen.place(in_ = container, x = 0, y = 0, relwidth = 1, relheight = 1)
        
        introScreenButton = Button(buttonFrame, text = "Go to Intro Screen", 
                                command = introScreen.lift, width = 30, height = 2)
        edaScreenButton = Button(buttonFrame, text = "Understand your data in detail", 
                                command = edaScreen.lift, width = 30, height = 2)
        
        edaScreenButton.pack(side = "left")
        introScreenButton.pack(side = "left")
        
        introScreen.show()

class IntroScreen(Page):

    def __init__(self, *args, **kwargs):

        Page.__init__(self, *args, **kwargs)
        self.backgroundImage = PhotoImage(file = "What is PD.png") 
        #^^ replace with something describing how to use the tool
        backgroundLabel = Label(self, image = self.backgroundImage)
        backgroundLabel.place(x = 0, y = 0, relwidth = 1, relheight = 1)

编辑:我的 createHTML 如下所示。它与 Tkinter(和工作)无关。它位于一个名为 HTMLCreator 的单独文件中。整个文件都放在那里。我添加了 import 语句,以便您可以毫无问题地运行代码。

import pandas as pd
from pandas import Series
# from pygame import mixer # Load the required library
import seaborn as sns
import matplotlib.pyplot as plt
import glob
import sweetviz as sv

def createHTML(df,feature_cols,target_col):
    """
    Create the HTML reports for the dataset given the names
    Params:
    df: dataframe passed,
    feature_cols: The independent variables (what you input)
    target_col: The dependent vars (what you predict)
    """
    data= df
    ##TODO Set the y_all and target_cols in a way that they get Tk input
    y_all=data.loc[:, target_col[0]:target_col[1]]
    target_col_names = data.loc[:, target_col[0]:target_col[1]].columns.values
    for col in target_col_names:
        X_all = data.loc[:, feature_cols[0]:feature_cols[1]]
        # print(y_all[col])
        X_all[col]=y_all[col]
        # print(X_all[col])
        advert_report=""
        if(len(X_all.columns.values)>50):
            advert_report = sv.analyze(X_all,pairwise_analysis="off",target_feat=col)
        else:
            print("here")
            advert_report = sv.analyze(X_all,pairwise_analysis="on",target_feat=col)

        #display the report
        
        advert_report.show_html('Breakdowns/'+col+'.html')
    
    advert_report = sv.analyze(y_all,pairwise_analysis="on")
        #display the report
        
    advert_report.show_html('Breakdowns/Preds'+'.html')

【问题讨论】:

  • 可能是因为您创建的是root = Toplevel() 而不是root = Tk()?因为我在其他地方看不到问题可能出在哪里,也许是因为我不经常使用 OOP 和 tkinter
  • 尝试使用 Tk()。还是同样的问题。
  • 关闭是什么意思?
  • 你在别处使用whileloop吗?
  • 如果生成报告是最后发生的事情,那么很有可能至少可以在此处找到问题的提示。另外,我看到了except: pass,这是一个坏习惯,因为如果发生错误你甚至都不会注意到。始终至少打印或记录异常。

标签: python-3.x user-interface tkinter


【解决方案1】:

在最初生成部分报告后,我确实遇到了一些问题,但就我而言,Tk 窗口没有关闭。

错误与您的 HTMLCreator 文件中的以下行有关:

if(len(X_all.columns.values)>50):
    advert_report = sv.analyze(X_all,pairwise_analysis="off",target_feat=col)
else:
    print("here")
    advert_report = sv.analyze(X_all,pairwise_analysis="on",target_feat=col)

Sweetviz 根据文档,目前仅支持 BOOLEAN 和 NUMERICAL 功能作为目标:

target_feat: 一个字符串,表示要成为的特征的名称 标记为“目标”。只有 BOOLEAN 和 NUMERICAL 特征可以作为目标 暂时。

这样通过运行如下代码,错误就不会出现:

if(len(X_all.columns.values)>50):
    advert_report = sv.analyze(X_all,pairwise_analysis="off")
else:
    print("here")
    advert_report = sv.analyze(X_all,pairwise_analysis="on")

然而,只传递一个数字列作为 target 仍然奇怪地引发错误,但您可以使用 FeatureConfig 对象作为解决方法来强制数字列的目标,如果该列不是数字列输入,你仍然得到一个错误。

feature_config = sv.FeatureConfig(force_num=col)
if(len(X_all.columns.values)>50):
    advert_report = sv.analyze(X_all, pairwise_analysis="off", feat_cfg=feature_config, target_feat=col)
else:
    print("here")
    advert_report = sv.analyze(X_all, pairwise_analysis="on", feat_cfg=feature_config, target_feat=col)

【讨论】:

  • 对我来说执行没有错误。 Tkinter 只为我关闭
  • 您必须以其他人可以重现问题的方式来表述您的问题。
  • 我不明白。这个问题有什么不清楚的地方吗?代码是这样的,所以我不明白为什么它不清楚。
  • 我不确定您是否提供了足够的信息来重现该问题。根据您提供的信息,我无法重现该问题。例如,“当你没有主循环时,这似乎是一个问题”是什么意思?您是否将整个代码导入另一个主文件?
  • 这就是字面意思。我的整个代码。我之所以说 Mainloop,是因为它在网上是这么说的。你认为你可以分享你拥有的代码吗?我开始认为这可能是我的系统。
【解决方案2】:

所以我在使用其他 EDA 工具(如 Pandas Profiling)后发现了原因。显然,所有基于 Pandas Profiling 的工具都在完成后(出于某种原因)在 TKinter 下。没有什么可以做的。

【讨论】:

    【解决方案3】:

    mainloop() 必须跟踪被调用的函数(在您的情况下进行数据分析)。
    例如。

    tk = Tk()
    tk.title('Data Analysis')
    data_analysis_func(args)
    tk.mainloop()
    

    【讨论】:

    猜你喜欢
    • 2015-02-22
    • 1970-01-01
    • 2021-06-05
    • 1970-01-01
    • 2012-06-16
    • 1970-01-01
    • 2023-02-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多