Hey I am having a problem during connecting two Gui together as when button pressed i want the tkinter to open another gui from another file.
File one contains the frontend dashboard and when you click on the teacher than click on login it gives me an error saying.
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\AppData\Local\Programs\Python\Python37-32\lib\tkinter\__init__.py", line 1705, in __call__
return self.func(*args)
TypeError: __init__() missing 1 required positional argument: 'master'
this is the main page Source Code:
from tkinter import *
from login import *
import tkinter as tk
from tkinter import ttk
class Frontend(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.title('Portal') # set the title of the main window
self.geometry('300x300') # set size of the main window to 300x300 pixels
# this container contains all the pages
container = tk.Frame(self)
container.pack(side='top', fill='both', expand=True)
container.grid_rowconfigure(0, weight=1) # make the cell in grid cover the entire window
container.grid_columnconfigure(0,weight=1) # make the cell in grid cover the entire window
self.frames = {} # these are pages we want to navigate to
for F in (Dashboard, Teacher, Student): # for each page
frame = F(container, self) # create the page
self.frames[F] = frame # store into frames
frame.grid(row=0, column=0, sticky='nsew') # grid it to container
self.show_frame(Dashboard) # let the first page is Dashboard
def show_frame(self, name):
frame = self.frames[name]
frame.tkraise()
class Dashboard(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self,parent)
label = ttk.Label(self, text="Main Screen", font=LARGE_FONT)
label.pack(pady=10,padx=10)
button = ttk.Button(self, text="Teacher",
command=lambda: controller.show_frame(Teacher))
button.pack()
button1 = ttk.Button(self, text="Student",
command=lambda: controller.show_frame(Student))
button1.pack()
class Teacher(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = ttk.Label(self, text="Teacher Login", font=LARGE_FONT)
label.pack(pady=10,padx=10)
#logo = ImageTk.PhotoImage(Image.open('logo.png'))
button = ttk.Button(self, text="Login", command=LoginFrame)
button.pack()
button1 = ttk.Button(self, text="Home",
command=lambda: controller.show_frame(Dashboard))
button1.pack()
class Student(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = ttk.Label(self, text="Student Login", font=LARGE_FONT)
label.pack(pady=10,padx=10)
button = ttk.Button(self, text="Home",
command=lambda: controller.show_frame(Dashboard))
button.pack()
def main():
root = Frontend()
root.mainloop()
if __name__=='__main__':
main()
Login source code:
from tkinter import *
import tkinter.messagebox as tm
class LoginFrame(Frame):
def __init__(self, master):
super().__init__(master)
self.label_username = Label(self, text="Username")
self.label_password = Label(self, text="Password")
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.entry_username.grid(row=0, column=1)
self.entry_password.grid(row=1, column=1)
self.checkbox = Checkbutton(self, text="Keep me logged in")
self.checkbox.grid(columnspan=2)
self.logbtn = Button(self, text="Login", command=self._login_btn_clicked)
self.logbtn.grid(columnspan=2)
self.pack()
def _login_btn_clicked(self):
# print("Clicked")
username = self.entry_username.get()
password = self.entry_password.get()
# print(username, password)
if username == "admin" and password == "admin123":
tm.showinfo("Login info", "Welcome Admin")
else:
tm.showerror("Login error", "Incorrect username")
def main():
root = Tk()
page = LoginFrame(root)
root.mainloop()
if __name__=='__main__':
main()
Thanks
Related
With the code below (that I took from sentdex) I am trying to raise PageOne window when the correct password("123") is inserted in the first page. However, I get the error: TypeError: show_frame() missing 1 required positional argument: 'cont'. Isn't PageOne the argument ? Why is not working ? Could you also please explain what "controller" variable does ?
Thank you very much in advance.
import tkinter as tk
import tkinter as tk
from PIL import Image,ImageTk
LARGE_FONT= ("Verdana", 12)
class Root(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
container = tk.Frame(self)
container.pack(side="top", fill="both", expand = True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
for F in (StartPage, PageOne, PageTwo):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(StartPage)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self,parent)
self.entry=tk.Entry(self, width = 35)
self.entry.insert(0, 'Enter password')
self.entry.config(fg = "grey")
# entry.bind('<FocusIn>', self.EntryFieldClicked)
# entry.bind("<Return>", (lambda event: self.SubmitPass()))
self.entry.place(relx=.5, rely=.3,anchor = tk.CENTER)
button=tk.Button( self,text="Show Password", width = 20,command = self.ShowPass).place(relx=.5, rely=.4,anchor = tk.CENTER)
button=tk.Button(self,text="Submit",width = 20, command=self.SubmitPass).place(relx=.5, rely=.5,anchor = tk.CENTER)
self.entry.config(fg = "grey")
self.entry.bind('<FocusIn>', self.EntryFieldClicked)
self.entry.bind("<Return>", (lambda event: self.SubmitPass ))
label=tk.Label(self,text="Log in to continue")
label.pack()
button = tk.Button(self, text="Visit Page 1",
command=lambda: controller.show_frame(PageOne))
button.pack()
def EntryFieldClicked(self,event):
if self.entry.get() == 'Enter password':
self.entry.delete(0, tk.END)
self.entry.insert(0, '')
self.entry.config(fg = 'black', show = "*")
def ShowPass(self):
self.entry.config(fg = 'black', show = "")
def SubmitPass(self):
global Password
Password = self.entry.get()
if Password == "123":
Root.show_frame(PageOne)
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="Page One!!!", font=LARGE_FONT)
label.pack(pady=10,padx=10)
self.controller = controller
button1 = tk.Button(self, text="Back to Home",
command=lambda: self.controller.show_frame(StartPage))
button1.pack()
button2 = tk.Button(self, text="Page Two",
command=lambda: controller.show_frame(PageTwo))
button2.pack()
class PageTwo(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="Page Two!!!", font=LARGE_FONT)
label.pack(pady=10,padx=10)
button1 = tk.Button(self, text="Back to Home",
command=lambda: controller.show_frame(StartPage))
button1.pack()
button2 = tk.Button(self, text="Page One",
command=lambda: controller.show_frame(PageOne))
button2.pack()
app = Root()
app.mainloop()
Blockquote
The problem is this line:
Root.show_frame(PageOne)
You are calling the method on the class rather than the instance, so the first argument is passes to the self parameter.
Your class needs to keep a reference to the controller, so that you can call the method via the controller.
class StartPage(tk.Frame):
def __init__(self, parent, controller):
self.controller = controller
...
def SubmitPass(self):
global Password
Password = self.entry.get()
if Password == "123":
self.controller.show_frame(PageOne)
I'm new to Graphic User Interface using Python. I was able to open the register page after clicking the Register button from the login page.
Below is the code files:
login.py
from tkinter import *
from tkinter import ttk
from register import Register
class Login:
def __init__(self):
self.loginw = Tk()
self.loginw.title("Login")
self.loginw.geometry("500x500")
self.signin = Button(self.loginw,width=20, text="Register", command=self.register)
self.signin.place(relx=0.5, rely=0.5, anchor=CENTER)
def register(self):
win = Toplevel()
Register(win)
w=Login()
w.loginw.mainloop()
register.py
from tkinter import *
from tkinter import ttk
class Register:
def __init__(self, win):
self.reg = win
self.reg.title("Register")
self.reg.geometry("500x500")
self.revert = Button(self.reg,width=20, text="Return to Login")
self.revert.place(relx=0.5, rely=0.5, anchor=CENTER)
self.reg.mainloop()
Is there a way to write the code like:
After clicking the register button from the login page, the register page pops up and the login page disappears.
After clicking the Return to Login button from the register page, the register page disappears, and the login page comes back.
Thank you so much.
Taken from another stackoverflow question:
import tkinter as tk # python 3
from tkinter import font as tkfont # python 3
class SampleApp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.title_font = tkfont.Font(family='Helvetica', size=18, weight="bold", slant="italic")
# the container is where we'll stack a bunch of frames
# on top of each other, then the one we want visible
# will be raised above the others
container = tk.Frame(self)
container.pack(side="top", fill="both", expand=True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
for F in (StartPage, PageOne, PageTwo):
page_name = F.__name__
frame = F(parent=container, controller=self)
self.frames[page_name] = frame
# put all of the pages in the same location;
# the one on the top of the stacking order
# will be the one that is visible.
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame("StartPage")
def show_frame(self, page_name):
'''Show a frame for the given page name'''
frame = self.frames[page_name]
frame.tkraise()
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text="This is the start page", font=controller.title_font)
label.pack(side="top", fill="x", pady=10)
button1 = tk.Button(self, text="Go to Page One",
command=lambda: controller.show_frame("PageOne"))
button2 = tk.Button(self, text="Go to Page Two",
command=lambda: controller.show_frame("PageTwo"))
button1.pack()
button2.pack()
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text="This is page 1", font=controller.title_font)
label.pack(side="top", fill="x", pady=10)
button = tk.Button(self, text="Go to the start page",
command=lambda: controller.show_frame("StartPage"))
button.pack()
class PageTwo(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text="This is page 2", font=controller.title_font)
label.pack(side="top", fill="x", pady=10)
button = tk.Button(self, text="Go to the start page",
command=lambda: controller.show_frame("StartPage"))
button.pack()
if __name__ == "__main__":
app = SampleApp()
app.mainloop()
In your case class StartPage could be your register page and PageOne your Login page. take that piece of code as a base to start.
Switch between two frames in tkinter
In this case the SampleApp class acts like the master frame (is a container) for other frames. So there is no pop up windows.
Another base template for tkinter app. Taken from the same link:
import tkinter as tk
class SampleApp(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self._frame = None
self.switch_frame(Register)
def switch_frame(self, frame_class):
"""Destroys current frame and replaces it with a new one."""
new_frame = frame_class(self)
if self._frame is not None:
self._frame.destroy()
self._frame = new_frame
self.geometry('925x600+'+self.screen()+'+20')
self._frame.pack()
def screen(self):
screen_width = self.winfo_screenwidth()
posX = (screen_width //2) - (925//2)
return str(posX)
class Register(tk.Frame):
def __init__(self, master):
tk.Frame.__init__(self, master)
tk.Label(self, text="This is the register Page").pack(side="top", fill="x", pady=10)
tk.Button(self, text="Login",
command=lambda: master.switch_frame(Login)).pack()
class Login(tk.Frame):
def __init__(self, master):
tk.Frame.__init__(self, master)
tk.Label(self, text="Login Page").pack(side="top", fill="x", pady=10)
self.usuario = tk.Entry(self)
self.usuario.insert(-1, 'User')
self.usuario.config(foreground='gray')
self.usuario.pack(side="top", fill="x", padx=10, ipady=3)
self.password = tk.Entry(self)
self.password.insert(-1, "Password")
self.password.config(foreground='gray')
self.password.pack(side="top", fill="x", pady=10, padx=10, ipady=3)
tk.Button(self, text="Return to register",
command=lambda: master.switch_frame(Register)).pack()
tk.Button(self, text="Login",
command=lambda: print("not implemented yet")).pack()
if __name__ == "__main__":
app = SampleApp()
app.mainloop()
edit: to answer another question:
To change the title (in the first example) you must call inside one of these classes StartPage, PageOne, PageTwo
controller.title("the title you want")
That is because in this part of code (in the class SampleApp, the main class) you are passing itself as second parameter.
self.frames = {}
for F in (StartPage, PageOne, PageTwo):
page_name = F.__name__
frame = F(parent=container, controller=self) //controller=self
self.frames[page_name] = frame
In the main class (SampleApp) you would do:
self.title("Some title")
In the second example:
master.title("Login") //inside Login or Register
self.title("Something") //inside SampleApp
So basically I am working on creating a program with different windows/frames. On each of these frames I am looking to have a different mini program for example one window allowing for a login page and then another allowing for registering. Currently I am able to switch between each frame with buttons and have labels on each frame. I have a separate program which allows for the registration of an account and information about them and then another separate program which allows for the logging in of an account which checks if that information is correct within the database which is created.
My main problem now is basically merging this altogether with different frames allowing for different functions on my overall program. My main problem currently is whenever I add in an entry box the program proceeds to give errors for my init which I don't understand.(Sorry I am not very advanced in my programming knowledge to be able to do this so that's why I am asking for help)
[
from tkinter import *
from tkinter import ttk
from tkinter import messagebox
import sqlite3
class App(Tk):
def __init__(self, *args, **kwargs):
Tk.__init__(self, *args, **kwargs)
Tk.iconbitmap(self, default="fishicon3.ico")
Tk.wm_title(self, "Crumlin Fishing Club")
#Setup Menu
MainMenu(self)
#Setup Frame
container = Frame(self)
container.pack(side="top", fill="both", expand = True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
for F in (StartPage, PageOne, PageTwo):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(StartPage)
def show_frame(self, context):
frame = self.frames[context]
frame.tkraise()
class StartPage(Frame):
def __init__(self, parent, controller):
Frame.__init__(self, parent)
label = Label(self, text="Start Page")
label.place(x=30,y=5)
start_page = ttk.Button(self, text="Start Page", command=lambda:controller.show_frame(StartPage))
start_page.place(x=25,y=25)
page_one = ttk.Button(self, text="Page One", command=lambda:controller.show_frame(PageOne))
page_one.place(x=25,y=50)
page_two = ttk.Button(self, text="Page Two", command=lambda:controller.show_frame(PageTwo))
page_two.place(x=25,y=75)
lblWelcome = Label(self, text="WELCOME! Welcome to the website of the Crumlin and District Angling Association owners of the fishing rights to the Crumlin River, Co. Antrim.",width=115,font=("bold", 10))
lblWelcome.place(x=500,y=50)
class PageOne(Frame):
def __init__(self, parent, controller):
Frame.__init__(self, parent)
label = Label(self, text="Page One")
label.place(x=30,y=5)
firstNameLabel = Label(self, text="First Name",width=20,font=("bold", 10))
firstNameLabel.place(x=350,y=100)
secondNameLabel = Label(self, text="Second Name",width=20,font=("bold", 10))
secondNameLabel.place(x=350,y=125)
usernameLabel = Label(self, text="Username",width=20,font=("bold", 10))
usernameLabel.place(x=350,y=150)
passwordLabel = Label(self, text="Password",width=20,font=("bold", 10))
passwordLabel.place(x=350,y=175)
genderLabel = Label(self, text="Gender",width=20,font=("bold", 10))
genderLabel.place(x=350,y=200)
countryLabel = Label(self, text="Country",width=20,font=("bold", 10))
countryLabel.place(x=350,y=225)
start_page = ttk.Button(self, text="Start Page", command=lambda:controller.show_frame(StartPage))
start_page.place(x=25,y=25)
page_one = ttk.Button(self, text="Page One", command=lambda:controller.show_frame(PageOne))
page_one.place(x=25,y=50)
page_two = ttk.Button(self, text="Page Two", command=lambda:controller.show_frame(PageTwo))
page_two.place(x=25,y=75)
def database():
Username = username.get()
Password = password.get()
Gender = gender.get()
Country = country.get()
Animal = animal.get()
FirstName = firstName.get()
SecondName = secondName.get()
conn = sqlite3.connect('Database1.db')
with conn:
cursor=conn.cursor()
cursor.execute('CREATE TABLE IF NOT EXISTS Student (FirstName TEXT,SecondName TEXT,Gender TEXT,Country TEXT,Animal TEXT,username TEXT,password TEXT)')
cursor.execute('INSERT INTO Student (FirstName,SecondName,Gender,Country,Animal,Username,Password) VALUES(?,?,?,?,?,?,?)',(FirstName,SecondName,Gender,Country,Animal,Username,Password))
conn.commit()
class PageTwo(Frame):
def __init__(self, parent, controller):
Frame.__init__(self, parent)
label = Label(self, text="Page Two")
label.place(x=30,y=5)
start_page = ttk.Button(self, text="Start Page", command=lambda:controller.show_frame(StartPage))
start_page.place(x=25,y=25)
page_one = ttk.Button(self, text="Page One", command=lambda:controller.show_frame(PageOne))
page_one.place(x=25,y=50)
page_two = ttk.Button(self, text="Page Two", command=lambda:controller.show_frame(PageTwo))
page_two.place(x=25,y=75)
class MainMenu:
def __init__(self, master):
menubar = Menu(master)
filemenu = Menu(menubar, tearoff=0)
filemenu.add_command(label="Exit", command=master.quit)
menubar.add_cascade(label="File", menu=filemenu)
master.config(menu=menubar)
app=App()
app.geometry("1900x1000+0+0")
app.mainloop()
So thats basically the windows of my main program and I am trying to implement then on "page one" registration for an account and then on another page a login function but for now I will show my registration program only as I do not know how to implement this on page one.
from tkinter import *
import sqlite3
root = Tk()
root.geometry('800x400')
root.title("Membership Application")
username=StringVar()
password=StringVar()
gender=StringVar()
country=StringVar()
animal=StringVar()
firstName=StringVar()
secondName=StringVar()
def database():
Username=username.get()
Password=password.get()
Gender=gender.get()
Country=country.get()
Animal=animal.get()
FirstName=firstName.get()
SecondName=secondName.get()
conn = sqlite3.connect('Database1.db')
with conn:
cursor=conn.cursor()
cursor.execute('CREATE TABLE IF NOT EXISTS Student (FirstName TEXT,SecondName TEXT,Gender TEXT,Country TEXT,Animal TEXT,username TEXT,password TEXT)')
cursor.execute('INSERT INTO Student (FirstName,SecondName,Gender,Country,Animal,Username,Password) VALUES(?,?,?,?,?,?,?)',(FirstName,SecondName,Gender,Country,Animal,Username,Password))
conn.commit()
title = Label(root, text="Registration form",width=20,font=("bold", 20))
title.place(x=90,y=53)
firstNameLabel = Label(root, text="First Name",width=20,font=("bold", 10))
firstNameLabel.place(x=50,y=100)
firstNameEntry = Entry(root,textvar=firstName)
firstNameEntry.place(x=200,y=100)
secondNameLabel = Label(root, text="Second Name",width=20,font=("bold", 10))
secondNameLabel.place(x=50,y=125)
secondNameEntry = Entry(root,textvar=secondName)
secondNameEntry.place(x=200,y=125)
usernameLabel = Label(root, text="Username",width=20,font=("bold", 10))
usernameLabel.place(x=350,y=100)
usernameEntry = Entry(root,textvar=username)
usernameEntry.place(x=500,y=100)
passwordLabel = Label(root, text="Password",width=20,font=("bold", 10))
passwordLabel.place(x=350,y=125)
passwordEntry = Entry(root,textvar=password, show ="*")
passwordEntry.place(x=500,y=125)
genderLabel = Label(root, text="Gender",width=20,font=("bold", 10))
genderLabel.place(x=70,y=230)
Radiobutton(root, text="Male",padx = 5, variable=gender, value="Male").place(x=235,y=230)
Radiobutton(root, text="Female",padx = 20, variable=gender, value="Female").place(x=290,y=230)
countryLabel = Label(root, text="Country",width=20,font=("bold", 10))
countryLabel.place(x=70,y=280)
countryList = ['Canada','India','UK','Nepal','Iceland','South Africa'];
droplist=OptionMenu(root,country, *countryList)
droplist.config(width=15)
country.set('Select your country')
droplist.place(x=240,y=280)
label_4 = Label(root, text="Animals",width=20,font=("bold", 10))
label_4.place(x=85,y=330)
animal2= IntVar()
Checkbutton(root, text="Dog", variable=animal).place(x=235,y=330)
Checkbutton(root, text="Cat", variable=animal2).place(x=290,y=330)
Button(root, text='Submit',width=20,bg='brown',fg='white',command=database).place(x=500,y=280)
root.mainloop()
This last bit wouldnt turn into code but this is still part of the registration program.
So basically how do I implement this I have tried multiple ways of trying to bring over the entry boxes and have the database work as well but this just isn't merging together and there is nowhere I have looked explaining how to do this specific task of having different features on each frame.
I have a problem with my code. I am unable to pass a variable to another class once a submit button is pressed in my tkinter frame.
I have followed the advice from a post already (How to access variables from different classes in tkinter?), which has helped but I still have issues.
From where to where I need these variables is commented on the code below:
import tkinter as tk
from tkinter import StringVar
LARGE_FONT = ("Verdana", 12)
class Club(tk.Tk):
def get_page(self, page_class):
return self.frames[page_class]
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
container = tk.Frame(self)
container.pack(side="top", fill="both", expand=True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.shared_data = {
"username": tk.StringVar(),
"password": tk.StringVar(),
}
self.frames = {}
for F in (Terminal, newUser, newUserSubmitButton, delUser):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(Terminal)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class Terminal(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="Welcome to the club terminal. Click the options below", font=LARGE_FONT)
label.grid(columnspan=3)
button = tk.Button(self, text="Visit new User",
command=lambda: controller.show_frame(newUser))
button.grid(row=1, column=0)
button2 = tk.Button(self, text="Visit del User",
command=lambda: controller.show_frame(delUser))
button2.grid(row=1, column=1)
class newUser(tk.Frame):
def __init__(self, parent, controller):
def submitButton():
username = self.controller.shared_data["username"].get()
print(username)
controller.show_frame(newUserSubmitButton)
##username variable from here to...
tk.Frame.__init__(self, parent)
welcomelabel = tk.Label(self, text="Add New User/s", font=LARGE_FONT)
welcomelabel.grid(columnspan=2, sticky="ew")
userNameLabel = tk.Label(self, text="Username")
userNameLabel.grid(row=1, column=0, sticky="e")
userNameEntry = tk.Entry(self, textvariable=self.controller.shared_data["username"])
userNameEntry.grid(row=1, column=1)
userMemTypeLabel = tk.Label(self, text="Membership Type")
userMemTypeLabel.grid(row=2, column=0, sticky="e")
variable = StringVar(self)
variable.set("Full")
userMemTypeMenu = tk.OptionMenu(self, variable, "Full", "Half")
userMemTypeMenu.grid(row=2, column=1)
userMemYearsLabel = tk.Label(self, text="Years that member is in the club")
userMemYearsLabel.grid(row=3, column=0, sticky="e")
userMemYearsEntry = tk.Entry(self)
userMemYearsEntry.grid(row=3, column=1)
self.controller = controller
newusersubmitbutton = tk.Button(self, text="submit", command=submitButton)
newusersubmitbutton.grid(columnspan=2)
class newUserSubmitButton(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
##username variable goes here
page1 = self.controller.get_page(newUser.submitButton)
page1.username.set("Hello, world")
print(page1)
class delUser(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="del User!!!", font=LARGE_FONT)
label.pack(pady=10, padx=10)
button1 = tk.Button(self, text="Back to Home",
command=lambda: controller.show_frame(Terminal))
button1.pack()
button2 = tk.Button(self, text="new User",
command=lambda: controller.show_frame(newUser))
button2.pack()
app = Club()
app.title("Club Terminal")
app.iconbitmap("table.ico")
app.mainloop()
Whenever I run this code, I get an AttributeError: 'newUser' object has no attribute 'controller'.
Any help is greatly appreciated, I'll be more than happy to try any ideas out.
With regards.
There are more problems in this code, but to solve that one, add the line:
self.controller=controller
To the newUser classes __init__ function.
I use a python program called Thonny. Its used to make another box that said 'You have made it into the main application' inside but I removed that piece of text for now. I would like it to show a options button and a change password button. This is the code:
import tkinter as tk
class Mainframe(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.frame = FirstFrame(self)
self.frame.pack()
def change(self, frame):
self.frame.pack_forget() # delete currrent
frame = frame(self)
self.frame.pack() # make new frame
class FirstFrame(tk.Frame):
def __init__(self, master=None, **kwargs):
tk.Frame.__init__(self, master, **kwargs)
master.title("Enter password")
master.geometry("300x200")
self.status = tk.Label(self, fg='red')
self.status.pack()
lbl = tk.Label(self, text='Enter password')
lbl.pack()
self.pwd = tk.Entry(self, show="*")
self.pwd.pack()
self.pwd.focus()
self.pwd.bind('<Return>', self.check)
btn = tk.Button(self, text="Done", command=self.check)
btn.pack()
btn = tk.Button(self, text="Cancel", command=self.quit)
btn.pack()
def check(self, event=None):
if self.pwd.get() == 'password':
self.master.change(SecondFrame)
else:
self.status.config(text="Wrong password")
class SecondFrame(tk.Frame):
def __init__(self, master=None, **kwargs):
tk.Frame.__init__(self, master, **kwargs)
master.title("Main application")
master.geometry("600x400")
def options_button(self):
def set_password(self):
e = tk.Entry(master, show="*", textvariable=self.password_set2)
e.pack()
but1 = tk.Button(self, text="Done", command=self.password_set)
but1.pack()
b = tk.Button(self, text="Set your password", command=self.set_password)
b.pack()
c = tk.Button(self, text="Options", command=self.options_button)
c.pack()
if __name__=="__main__":
app=Mainframe()
app.mainloop()
This is What is not working.
This is what it originally did
So I had a little bit of a play around and I think this is what your after. I also changed your code a little bit as I always feel its best to put self infront of all widgets on multiclass applications.
import tkinter as tk
class FirstFrame(tk.Frame):
def __init__(self, master, **kwargs):
tk.Frame.__init__(self, master, **kwargs)
self.pack()
master.title("Enter password")
master.geometry("300x200")
self.status = tk.Label(self, fg='red')
self.status.pack()
self.lbl = tk.Label(self, text='Enter password')
self.lbl.pack()
self.pwd = tk.Entry(self, show="*")
self.pwd.pack()
self.pwd.focus()
self.pwd.bind('<Return>', self.check)
self.btn = tk.Button(self, text="Done", command=self.check)
self.btn.pack()
self.btn = tk.Button(self, text="Cancel", command=self.quit)
self.btn.pack()
def check(self, event=None):
if self.pwd.get() == app.password:
self.destroy() #destroy current window and open next
self.app= SecondFrame(self.master)
else:
self.status.config(text="Wrong password")
class SecondFrame(tk.Frame):
#re organised a lot in here
def __init__(self, master, **kwargs):
tk.Frame.__init__(self, master, **kwargs)
self.pack()
master.title("Main application")
master.geometry("600x400")
self.c = tk.Button(self, text="Options", command=self.options_button)
self.c.pack()
self.e = tk.Entry(self.master, show="*")
def options_button(self):
self.e.pack()
self.but1 = tk.Button(self, text="Change password", command=self.set_password)
self.but1.pack()
def set_password(self):
app.password=self.e.get()
if __name__=="__main__":
root = tk.Tk() #removed your mainframe class
app=FirstFrame(root)
#set an attribute of the application for the password
#similar to a global variable
app.password = "password"
root.mainloop()
So with what I have done you get prompted for the password and if you get it right it goes to the next scree, then an options button appears and if it is clicked then an entry box appears allowing the user to change the password