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