简体   繁体   中英

Destroy function not destroying a frame efficiently after the first iteration in Tkinter Python

I have built a code that saves the calculated data at every iteration in a for loop and the results are stored in 3 different csv files. These saved results are read in another python code that displays the results using GUI tkinter on a window containing three different frames. These three frames are updated every 3 seconds perfectly.

I added a "close" button on each of the three frames that when pressed should DESTROY/CLOSE the specific frame only. At the first iteration and when I press the close button on any of the three frames, the destruction / closure of the frame is done perfectly. However, when time moves on and when more than 1 iteration is done, the close button doesn't close immediately.

For instance, say that 3 iterations and calculations have been done, so when I press the close button it will close on the FOURTH press and before that when it is pressed the frames will show the PREVIOUS results that were shown in the previous iteration .. How can that be edited ? I have attached my code below.


import random
from tkinter import*
import tkinter as tk
import csv
import numpy as np
import time
base = tk.Tk()
base.geometry("500x300")

frame1 = tk.LabelFrame(base, text="MVs ", width=240, height=330, bd=15)
frame2 = tk.LabelFrame(base, text="CVs ", width=240, height=330, bd=15)
frame3 = tk.LabelFrame(base, text="DVs ", width=240, height=330, bd=15)

def MVs():
    #read files from saved excel sheets

    MV=np.empty(8)

    with open("MVs.csv","r") as csv_file:

        count=0

        csv_reader=csv.reader(csv_file)
        for row in csv_reader:
            i=row[0]#change from string to float type
            MV[count]=i #update y array
            count +=1 # increment of 1 to get the number of total values

        MV=MV.reshape(8,1)


    frame1 = tk.LabelFrame(base, text="MVs", width=240, height=330, bd=15)


    frame1.grid(row=1, column=0,  padx=8)

    #Display row titles
    def exit_btn():

        frame1.destroy()
        #frame1.update()

    btn1_c=Button(frame1,text="Close",command=exit_btn).grid(column=1,columnspan=1,row=10,rowspan=1, sticky=W)    
    Label(frame1,text="Tc Measured").grid(column=0,columnspan=1,row=2,rowspan=1, sticky=W)
    Label(frame1,text="Tc Optimum").grid(column=0,columnspan=1,row=3,rowspan=1, sticky=W)
    Label(frame1,text="Tc Cost").grid(column=0,columnspan=1,row=4,rowspan=1, sticky=W)
    Label(frame1,text="Tc Weight").grid(column=0,columnspan=1,row=5,rowspan=1, sticky=W)

    Label(frame1,text="Q Measured").grid(column=0,columnspan=1,row=6,rowspan=1, sticky=W)
    Label(frame1,text="Q Optimum").grid(column=0,columnspan=1,row=7,rowspan=1, sticky=W)
    Label(frame1,text="Q Cost").grid(column=0,columnspan=1,row=8,rowspan=1, sticky=W)
    Label(frame1,text="Q Weight").grid(column=0,columnspan=1,row=9,rowspan=1, sticky=W)

    for i in range(8):
        Label(frame1,text= str(round(MV[i,0],5))).grid(column=1 ,columnspan=1,row=i+2,rowspan=1, sticky=W)


def CVs():

    CV=np.empty(8)

    with open("CVs.csv","r") as csv_file:

        count=0

        csv_reader=csv.reader(csv_file)
        for row in csv_reader:
            i=row[0]#change from string to float type
            CV[count]=i #update y array
            count +=1 # increment of 1 to get the number of total values

        CV=CV.reshape(8,1)

    frame2 = tk.LabelFrame(base, text="CVs", width=240, height=330, bd=15)

    frame2.grid(row=1, column=3,  padx=8)

    def exit_btn():

        frame2.destroy()
       # frame2.update()

    #Display row titles
    btn2_c=Button(frame2,text="Close",command=exit_btn).grid(column=3,columnspan=1,row=10,rowspan=1, sticky=W)    
    Label(frame2,text="T Measured").grid(column=3,columnspan=1,row=2,rowspan=1, sticky=W)
    Label(frame2,text="T Optimum").grid(column=3,columnspan=1,row=3,rowspan=1, sticky=W)
    Label(frame2,text="T Revenue").grid(column=3,columnspan=1,row=4,rowspan=1, sticky=W)
    Label(frame2,text="T Weight").grid(column=3,columnspan=1,row=5,rowspan=1, sticky=W)

    Label(frame2,text="Ca Measured").grid(column=3,columnspan=1,row=6,rowspan=1, sticky=W)
    Label(frame2,text="Ca Optimum").grid(column=3,columnspan=1,row=7,rowspan=1, sticky=W)
    Label(frame2,text="Ca Revenue").grid(column=3,columnspan=1,row=8,rowspan=1, sticky=W)
    Label(frame2,text="Ca Weight").grid(column=3,columnspan=1,row=9,rowspan=1, sticky=W)

    for i in range(8):
        Label(frame2,text= str(round(CV[i,0],5))).grid(column=4 ,columnspan=1,row=i+2,rowspan=1, sticky=W)

def DVs():

    dist=np.empty(1)

    with open("disturbance.csv","r") as csv_file:

        count=0

        csv_reader=csv.reader(csv_file)
        for row in csv_reader:
            i=row[0]#change from string to float type
            dist[count]=i #update y array
            count +=1 # increment of 1 to get the number of total values

        dist=dist.reshape(1,1)

    frame3 = tk.LabelFrame(base, text="DVs ", width=240, height=330, bd=15)

    frame3.grid(row=1, column=5,  padx=8)

    def exit_btn():

        frame3.destroy()
       # frame3.update()

    btn3_c=Button(frame3,text="Close",command=exit_btn).grid(column=5,columnspan=1,row=3,rowspan=1, sticky=W)    
    Label(frame3,text="Q Loss").grid(column=5,columnspan=1,row=2,rowspan=1, sticky=W)
    Label(frame3,text= str(round(dist[0,0],3))).grid(column=6 ,columnspan=1,row=2,rowspan=1, sticky=W)


btn1=Button(base,text='MVs',command=MVs)
btn2=Button(base,text='CVs',command=CVs)
btn3=Button(base,text='DVs',command=DVs)

btn1.grid(row=0,column=0)
btn2.grid(row=0,column=3)
btn3.grid(row=0,column=5)


i=0
show=True
#show results

while(show==True):

    #base.after(i, MVs) #in ms
    frame1.after(i, MVs)
    #frame1.after(i+100,frame1.destroy)
    #base.after(i, CVs) #in ms
    frame2.after(i, CVs)
    #frame2.after(i+100,frame2.destroy)
    #base.after(i, DVs) #in ms
    frame3.after(i, DVs)
    #frame3.after(i+100,frame3.destroy)

    base.update()#update display

    i=i+3000

base.mainloop()

I found a way that solves this problem. However, a new problem arises ..

Basically, I was defining frame1 inside the MVs function. I removed that and kept it only at the beginning. The same approach was done for frame2 and frame3. This way, when I press the close button, the respective frame is immediately closed. However, now when I have closed frame1 for instance, when I press the MVs button again, the frame1 is NOT opening again. It is giving me an error:

_tkinter.TclError: bad window path name ".!labelframe"

If I don't press the close button, this problem does not happen. Hence, the problem is definitely from destroying and closing the frames.

I have attached my edited code here:

import random
from tkinter import*
import tkinter as tk
import csv
import numpy as np
import time
base = tk.Tk()
base.geometry("500x300")



frame1 = tk.LabelFrame(base, text="MVs ", width=240, height=330, bd=15)
frame1.grid(row=1, column=0,  padx=8)


frame2 = tk.LabelFrame(base, text="CVs ", width=240, height=330, bd=15)
frame2.grid(row=1, column=3,  padx=8)

frame3 = tk.LabelFrame(base, text="DVs ", width=240, height=330, bd=15)
frame3.grid(row=1, column=5,  padx=8)


z=False

def MVs():
    #read files from saved excel sheets

    global z
    global frame1

    if z==True:

        frame1 = tk.LabelFrame(base, text="MVs", width=240, height=330, bd=15)

        frame1.grid(row=1, column=0,  padx=8)

    MV=np.empty(8)

    with open("MVs.csv","r") as csv_file:

        count=0

        csv_reader=csv.reader(csv_file)
        for row in csv_reader:
            i=row[0]#change from string to float type
            MV[count]=i #update y array
            count +=1 # increment of 1 to get the number of total values

        MV=MV.reshape(8,1)


    #Display row titles
    def exit_btn():

        z=True
        frame1.destroy()
        frame1.update()

    if z==False:

        Label(frame1,text="Tc Measured").grid(column=0,columnspan=1,row=2,rowspan=1, sticky=W)
        Label(frame1,text="Tc Optimum").grid(column=0,columnspan=1,row=3,rowspan=1, sticky=W)
        Label(frame1,text="Tc Cost").grid(column=0,columnspan=1,row=4,rowspan=1, sticky=W)
        Label(frame1,text="Tc Weight").grid(column=0,columnspan=1,row=5,rowspan=1, sticky=W)

        Label(frame1,text="Q Measured").grid(column=0,columnspan=1,row=6,rowspan=1, sticky=W)
        Label(frame1,text="Q Optimum").grid(column=0,columnspan=1,row=7,rowspan=1, sticky=W)
        Label(frame1,text="Q Cost").grid(column=0,columnspan=1,row=8,rowspan=1, sticky=W)
        Label(frame1,text="Q Weight").grid(column=0,columnspan=1,row=9,rowspan=1, sticky=W)

        for i in range(8):
            Label(frame1,text= str(round(MV[i,0],5))).grid(column=1 ,columnspan=1,row=i+2,rowspan=1, sticky=W)

        btn1_c=Button(frame1,text="Close",command=exit_btn).grid(column=1,columnspan=1,row=10,rowspan=1, sticky=W)

def CVs():

    global z
    global frame2

    if z==True:

        frame2 = tk.LabelFrame(base, text="CVs", width=240, height=330, bd=15)

        frame2.grid(row=1, column=3,  padx=8)

    CV=np.empty(8)

    with open("CVs.csv","r") as csv_file:

        count=0

        csv_reader=csv.reader(csv_file)
        for row in csv_reader:
            i=row[0]#change from string to float type
            CV[count]=i #update y array
            count +=1 # increment of 1 to get the number of total values

        CV=CV.reshape(8,1)

    #frame2 = tk.LabelFrame(base, text="CVs", width=240, height=330, bd=15)

    #frame2.grid(row=1, column=3,  padx=8)

    def exit_btn():

        z=True
        frame2.destroy()
        frame2.update()

    #Display row titles

    Label(frame2,text="T Measured").grid(column=3,columnspan=1,row=2,rowspan=1, sticky=W)
    Label(frame2,text="T Optimum").grid(column=3,columnspan=1,row=3,rowspan=1, sticky=W)
    Label(frame2,text="T Revenue").grid(column=3,columnspan=1,row=4,rowspan=1, sticky=W)
    Label(frame2,text="T Weight").grid(column=3,columnspan=1,row=5,rowspan=1, sticky=W)

    Label(frame2,text="Ca Measured").grid(column=3,columnspan=1,row=6,rowspan=1, sticky=W)
    Label(frame2,text="Ca Optimum").grid(column=3,columnspan=1,row=7,rowspan=1, sticky=W)
    Label(frame2,text="Ca Revenue").grid(column=3,columnspan=1,row=8,rowspan=1, sticky=W)
    Label(frame2,text="Ca Weight").grid(column=3,columnspan=1,row=9,rowspan=1, sticky=W)

    for i in range(8):
        Label(frame2,text= str(round(CV[i,0],5))).grid(column=4 ,columnspan=1,row=i+2,rowspan=1, sticky=W)

    btn2_c=Button(frame2,text="Close",command=exit_btn).grid(column=3,columnspan=1,row=10,rowspan=1, sticky=W)   

def DVs():

    dist=np.empty(1)

    with open("disturbance.csv","r") as csv_file:

        count=0

        csv_reader=csv.reader(csv_file)
        for row in csv_reader:
            i=row[0]#change from string to float type
            dist[count]=i #update y array
            count +=1 # increment of 1 to get the number of total values

        dist=dist.reshape(1,1)

    #frame3 = tk.LabelFrame(base, text="DVs ", width=240, height=330, bd=15)

    #frame3.grid(row=1, column=5,  padx=8)

    def exit_btn():

        frame3.destroy()
        frame3.update()

    btn3_c=Button(frame3,text="Close",command=exit_btn).grid(column=5,columnspan=1,row=3,rowspan=1, sticky=W)    
    Label(frame3,text="Q Loss").grid(column=5,columnspan=1,row=2,rowspan=1, sticky=W)
    Label(frame3,text= str(round(dist[0,0],3))).grid(column=6 ,columnspan=1,row=2,rowspan=1, sticky=W)


btn1=Button(base,text='MVs',command=MVs)
btn2=Button(base,text='CVs',command=CVs)
btn3=Button(base,text='DVs',command=DVs)

btn1.grid(row=0,column=0)
btn2.grid(row=0,column=3)
btn3.grid(row=0,column=5)


i=0
show=True
#show results

while(show==True):

    #base.after(i, MVs) #in ms
    frame1.after(i, MVs)
    #frame1.after(i+100,frame1.destroy)
    #base.after(i, CVs) #in ms
    frame2.after(i, CVs)
    #frame2.after(i+100,frame2.destroy)
    #base.after(i, DVs) #in ms
    frame3.after(i, DVs)
    #frame3.after(i+100,frame3.destroy)

    base.update()#update display

    i=i+3000

base.mainloop()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM