简体   繁体   中英

Why my tkinter back button does not function?

I made 2 pages in my tkinter. The main page have one button that will bring the user to Classifier_UI page. In the Classifier_UI page, I made a back button that will bring the user back to the main page. The back button works just fine if I run only the Classifier_UI.py. It did bring me back to the main page. However, if I run from the main_page.py, then click on the button that bring me to the Classifier_UI page, and click on the back button, the windows will automatically closed and did not bring me back to the main page. Why is this happening and how can I fix this?

Below is the button code that I made in my main page:

 from tkinter import *
    class Test:
        def __init__(self, tk):
            fm = Frame(tk)
            self.l1 = Label(tk, text="Welcome", font=("Helvetica", 38, 'bold'), bg='LightGoldenrod2', fg='gray24').place(relx=0.25, rely=0.15)
            self.b2 = Button(tk, bg='LightGoldenrod4', text="Classifier 1", font=("Helvetica", '10', 'bold'), foreground="white", width = 24, height = 3, command=self.change).pack(side=LEFT, expand=YES, padx=110, pady=300)
            fm.pack(fill=BOTH, expand=YES)
            
        def change(self):
            tk.destroy()
            import Classifier_UI
            
            img_path = StringVar()
            canvas = tk.Canvas(root, height = '700', width= '750', bg='#292828')
            canvas.pack(fill=BOTH)
    
    
    tk = Tk()
    tk['bg']='LightGoldenrod2'
    tk.toolbar = Frame(tk, bg="white")
    
    width= tk.winfo_screenwidth() 
    height= tk.winfo_screenheight()
    tk.geometry("%dx%d" % (width, height))
    tt = Test(tk)
    tk.mainloop()

This is code of the button in my second page:

def change():
        root.destroy()
        import main_page
  
root = tk.Tk()
root.title("Image Classifier")

browse = tk.Button(text="Back", bg='white', font='courier 10', command=change)
browse.place(relx = 0.75 ,rely = 0.85, relwidth = 0.12, relheight=0.05)

root.mainloop()

The problem is that tk.destroy() and root.destroy() close the window, because you're calling the destroy() method of the window, not the frame one. Try to do self.destroy() when your class is referring to a frame, this will destroy just the frame and not the entire window, but, when the frame is destroyed, you have no other way to make it reapper but to create another instance. Also, you shouldn't import modules inside functions unless you want to make that import optional, put all your imports at the start of the script if it's not the case.

More importantly, in both files you make a root window and destroy it, which is not necessary if you just want to change the displayed frame. I suggest you to put two frame inside the window, one on top of the other, and switch back and forth between the frames when the button is pressed.

Here is a simple example of code were a button switch between two frames (note that I've put the button straight inside the window and not inside a frame to make it indipendent from the change, but you can put one for each frame if you want):

import tkinter as tk


class MainWindow(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        self.frame_on_top = 1
        self.switch_frame_button = tk.Button(self, text='switch', command=self.switch_frame)
        self.switch_frame_button.grid(row=0, column=0)
        self.container = tk.Frame(self)    # This is the position where we will put the frames.
        self.container.grid(row=1, column=0)
        self.frames = {}
        counter = 2

        # Now let's make our frames.
        # Starting from the second, so that the first frame will be put on top (last in first out).
        for fr in (SecondFrame, FirstFrame):
            frame = fr(parent=self)
            self.frames[str(counter)] = frame
            frame.grid(row=1, column=0, sticky='nsew')  # Put all the frames in the same spot.
            counter -= 1

    def switch_frame(self):
    
        if self.frame_on_top == 1:
        frame = self.frames['2']
        frame.tkraise()
        self.frame_on_top = 2
    elif self.frame_on_top == 2:
        frame = self.frames['1']
        frame.tkraise()
        self.frame_on_top = 1


class FirstFrame(tk.Frame):

    def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        tk.Label(self, text='First frame').pack()


class SecondFrame(tk.Frame):

    def __init__(self, parent):    
        tk.Frame.__init__(self, parent)
        tk.Label(self, text='Second frame').pack()


root = MainWindow()
root.mainloop()

try making a button that it's command goes back to that function

def BackFunction(self):
    pass

def __init__(self):
    back = Button(root, command=self.BackFunction)

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