Tkinter won't close correctly and launch new file Tkinter won't close correctly and launch new file tkinter tkinter

Tkinter won't close correctly and launch new file


Consider initializing frames in a top level class, GUI, that handles opening of both frames where LoginFrame calls its parent's open_batch() (now lambda implemented) method. Below assumes LoginFrame.py and BatchFrame.py resides in same folder as GUI_App script.

In this way, scripts run as standalone modules on one Tk() instance.

GUIApp (calls child frames, LoginFrame, and BatchFrame)

from tkinter import *import LoginFrame as LFimport BatchFrame as BFclass GUI():    def __init__(self):            self.root = Tk()        self.root.title("SBSHREG")        self.root.geometry("235x120")        self.root.open_batch = self.open_batch        lf = LF.LoginFrame(self.root)        self.root.mainloop()    def open_batch(self):        bf = BF.BatchFrame(self.root)app = GUI()

LoginFrame

from tkinter import *import tkinter.messagebox as tmclass LoginFrame(Frame):    def __init__(self, master):        super().__init__(master)        self.label_username = Label(self, text="Username")        self.label_password = Label(self, text="Password")        self.photo = PhotoImage(file="sbshreg.png")        self.label_image = Label(self, image=self.photo)        self.label_image.image = self.photo        self.entry_username = Entry(self)        self.entry_password = Entry(self, show="*")        self.label_image.grid(row=0, column=2, rowspan=2, columnspan=2, sticky=W, padx=10)        self.label_username.grid(row=2, sticky=E)        self.label_password.grid(row=3, sticky=E)        self.entry_username.grid(row=2, column=1, sticky=E)        self.entry_password.grid(row=3, column=1, sticky=E)        self.logbtn = Button(self, text="Login", command=lambda: self._login_btn_clicked(master))        self.logbtn.grid(row=4, column=1, columnspan=2, sticky=S+E+N+W)        self.grid()    def _login_btn_clicked(self, controller):        username = self.entry_username.get()        password = self.entry_password.get()        if username == "123" and password == "123":            tm.showinfo("SBSHREG", "Welcome 123")            self.destroy()            controller.open_batch()        else:            tm.showerror("SBSHREG", "Incorrect username")

BatchFrame

from tkinter import *import tkinter.messagebox as tmfrom tkinter import ttk as ttkclass BatchFrame(Frame):    def __init__(self, master):        super().__init__(master)            self.photo = PhotoImage(file="sbshreg.png")        self.label_photo = Label(master, image=self.photo)        self.label_photo.image = self.photo        self.label_photo.grid(row=0, column=2, sticky=N, padx=10, pady=10)        #Add frame starting here        frame = LabelFrame(master, text='Voeg batch toe')        frame.grid (row=0, column=0, padx=10)        self.label_batch = Label(frame, text="Batchnummer")        self.label_employee = Label(frame, text="Medewerker")        self.label_material = Label(frame, text="Materiaalsoort")        self.label_weight = Label(frame, text="Gewicht")        self.entry_batch = Entry(frame)        self.entry_employee = Entry(frame)        self.entry_material= Entry(frame)        self.entry_weight = Entry(frame)        self.label_batch.grid(row=0, column=0, sticky=S+E+N+W, columnspan=2, padx=10)        self.label_employee.grid(row=2, column=0,  sticky=S+E+N+W, columnspan=2, padx=10)        self.label_material.grid(row=4, column=0,  sticky=S+E+N+W, columnspan=2, padx=10)        self.label_weight.grid(row=6, column=0,  sticky=S+E+N+W, columnspan=2, padx=10)        self.entry_batch.grid(row=1, column=0, sticky=S+E+N+W, columnspan=2, padx=10)        self.entry_employee.grid(row=3, column=0, sticky=S+E+N+W, columnspan=2, padx=10)        self.entry_material.grid(row=5, column=0, sticky=S+E+N+W, columnspan=2, padx=10)        self.entry_weight.grid(row=7, column=0, sticky=S+E+N+W, columnspan=2, padx=10)        self.btnadd = Button(frame, text='Voeg toe', command=self._btn_add_clicked)        self.btnadd.grid(column=0, row=8, pady=10)        #Search frame starting here        framesearch = LabelFrame(master, text='Zoek')        framesearch.grid(row=0, column=1, sticky=N)        self.label_batch = Label(framesearch, text="Batchnummer")        self.label_employee = Label(framesearch, text="Medewerker")        self.entry_batch = Entry(framesearch)        self.entry_employee = Entry(framesearch)        self.label_batch.grid(row=0, column=0, sticky=S, columnspan=2, padx=10)        self.label_employee.grid(row=2, column=0, sticky=S, columnspan=2, padx=10)        self.entry_batch.grid(row=1, column=0, sticky=S + E + N + W, columnspan=2, padx=10, pady=10)        self.entry_employee.grid(row=3, column=0, sticky=S + E + N + W, columnspan=2, padx=10, pady=10)        self.btnbatch = Button(framesearch, text="Zoek", command=self._btn_batch_clicked)        self.btnemployee = Button(framesearch, text="Zoek", command=self._btn_employee_clicked)        self.btnbatch.grid(columnspan=1, column=2, row=1, sticky=W, padx=10)        self.btnemployee.grid(columnspan=1, column=2, row=3, sticky=W, padx=10)        #This is the viewingarea for the data        self.tree = ttk.Treeview (height=10, columns=("Batchnummer", "Medewerker", "Materiaalsoort", "Gewicht"))        self.tree.grid (row=9, columnspan=10, padx=10, pady=10)        self.tree.heading('#1', text='Batchnummer', anchor=W)        self.tree.heading('#2', text='Medewerker', anchor=W)        self.tree.heading('#3', text='Materiaalsoort', anchor=W)        self.tree.heading('#4', text='Gewicht', anchor=W)        self.tree.column('#0', stretch=NO, minwidth=0, width=0)        self.tree.column('#1', stretch=NO, minwidth=0, width=100)        self.tree.column('#2', stretch=NO, minwidth=0, width=100)        self.tree.column('#3', stretch=NO, minwidth=0, width=100)        self.tree.column('#4', stretch=NO, minwidth=0, width=100)        self.grid()    def _btn_add_clicked(self):        batch = self.entry_batch.get()    def _btn_batch_clicked(self):        batch = self.entry_batch.get()    def _btn_employee_clicked(self):        batch = self.entry_employee.get()


I do not agree with the method of how you are invoking your 2nd python file.You really dont need to use exec here.

However if you really want to you need to add import tkinter.ttk as ttk to your first page for it to work right.

Your best option is to import the 2nd file on the 1st file and invoke it by calling the class name.

so for you imports on the first page you need to add import BatchFrame.

Then call it in your code.

Replace:

exec(open("./test2.py").read())

with:

BatchFrame.BatchFrame(root)

I do see one mistake in your BatchFrame class thought.

change this:

self.label_photo = Label(root, image=self.photo)

to this:

self.label_photo = Label(master, image=self.photo)

UPDATE:To address your issue from the comment make these changes:

1: Add this to your BatchFrame Class:

class BatchFrame(Frame):    def __init__(self, master):        super().__init__(master)        self.master = master # add this        self.master.title("SBSHREG") # and this        self.master.geometry("432x480") # and this

2: Remove this from your BatchFrame file:

root = Tk()root.title("SBSHREG")root.geometry("432x480")lf = BatchFrame(root)root.mainloop()

3: Add this to your LoginFrame class:

class LoginFrame(Frame):    def __init__(self, master):        super().__init__(master)        self.master = master # add this

4: In the LoginFrame class change this:

BatchFrame.BatchFrame(root)

to this:

BatchFrame.BatchFrame(self.master)


I recommend importing batchframe instead of executing it.

from tkinter import *import tkinter.messagebox as tmfrom tkinter import ttk as ttkfrom batchframe import BatchFrameclass LoginFrame(Frame):    def __init__(self, master):        super().__init__(master)        self.master = master        self.label_username = Label(self, text="Username")        self.label_password = Label(self, text="Password")        self.photo = PhotoImage(file="icon.png")        self.label_image = Label(root, image=self.photo)        self.label_image.image = self.photo        self.entry_username = Entry(self)        self.entry_password = Entry(self, show="*")        self.label_username.grid(row=0, sticky=E)        self.label_password.grid(row=1, sticky=E)        self.label_image.grid(row=3, column=2, rowspan=2, columnspan=2, sticky=W, padx=10)        self.entry_username.grid(row=0, column=1, sticky=E)        self.entry_password.grid(row=1, column=1, sticky=E)        self.logbtn = Button(self, text="Login", command=self._login_btn_clicked)        self.logbtn.grid(columnspan=2, column=1, row=2, sticky=S+E+N+W)        self.grid()    def _login_btn_clicked(self):        username = self.entry_username.get()        password = self.entry_password.get()        if username == "123" and password == "123":            tm.showinfo("SBSHREG", "Welcome 123")            #The sweet spot where all goes wrong...            self.destroy()            # Create the instance of the BatchFrame class, passing in self.master            self.batchframe = BatchFrame(self.master)        else:            tm.showerror("SBSHREG", "Incorrect username")

Then in batchframe.py change variable reference from root to master