Entry(self, textvar=firstName) gives NameError: name 'firstName' is not defined - python

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.

Related

In Python, how can I save a new input and relate it to a referenced SQL row?

Relevant code to the question can be found in class Database and class UserData.
I am attempting to learn how to use SQL. I have the account validation working the way I would like. The step I am stuck at is how I can save any new user data to the active account.
Specifically, how I can enter data in the tkinter frame generated by class UserData and then append that to the relevant account in the database. I am stuck on figuring out how to either extend the "users" table to contain this new info, or create a new "notes" table and add notes to this and form a relation to the active "users" row.
The practical way this works is: create account > login > enter text in textarea > save text to account > (view text to confirm functionality) > logout > login and have text auto-populate based on active account (if any had been saved prior)
I have some of the framework set up for those purposes, but am currently stumped and would appreciate any feedback.
import tkinter as tk
import tkinter.ttk as ttk
import sqlite3 as sql
BASE_FONT = ("Bookman Old Style", 10)
user_id = None
print(user_id) # for testing
# Generates database with two tables, and holds some queries
class Database:
def __init__(self, *args, **kwargs):
self.connection = sql.connect("accounts.db")
self.cursor = self.connection.cursor()
try:
self.cursor.execute(
"""CREATE TABLE IF NOT EXISTS users
(username TEXT NOT NULL, password TEXT NOT NULL);"""
)
except sql.OperationalError:
print("users table already exists")
try:
self.cursor.execute(
"""CREATE TABLE IF NOT EXISTS Notes
(NoteId INTEGER PRIMARY KEY,
NoteName TEXT NULL,
FOREIGN KEY (username) REFERENCES users(username);"""
)
except sql.OperationalError:
print("Notes table already exists")
def add_value(self, username, password):
self.cursor.execute("""INSERT INTO users VALUES (?,?)""", (username, password))
self.connection.commit()
# def add_note(self, note):
# self.cursor.execute("""
# INSERT INTO Notes (?,?,?)""", (1, "First Note", 777))
# # FIXME
def check_table(self, table="users"):
for row in self.cursor.execute(f"SELECT rowid, * FROM {table}"):
print(row)
db = Database()
# contains tkinter setup logic, to allow for switching frames
class LoginInterface(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
button_styling = ttk.Style()
button_styling.configure("my.TButton", font=BASE_FONT)
label_styling = ttk.Style()
label_styling.configure("my.TLabel", font=BASE_FONT)
tk.Tk.wm_title(self, "Login Screen")
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 (
Login,
Userdata,
CreateNew,
):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(Login)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
# contains first page of program.
class Login(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.label0 = ttk.Label(self, text="Login Interface")
self.label0.grid(row=0, column=0, padx=40, pady=10)
self.label1 = ttk.Label(self, text="Username: ", style="my.TLabel")
self.label1.grid(row=1, column=1)
self.username = ttk.Entry(self)
self.username.grid(row=1, column=2)
self.label2 = ttk.Label(self, text="Password: ", style="my.TLabel")
self.label2.grid(row=2, column=1, pady=10)
self.password = ttk.Entry(self, show="*")
self.password.grid(row=2, column=2, pady=10)
def login_func(event):
db.cursor.execute(
"SELECT username FROM users WHERE username = (?) AND password = (?)",
(
self.username.get(),
self.password.get(),
),
)
if db.cursor.fetchone():
print("found")
self.password.delete(0, tk.END)
controller.show_frame(Userdata)
try:
self.label3.destroy()
except AttributeError:
pass
global user_id
user_id = self.username.get()
print(user_id + ' in function')
else:
print("not found")
self.label3 = ttk.Label(self, text="Incorrect account info")
self.label3.grid(row=5, column=2)
self.login = ttk.Button(
self, text="Login", style="my.TButton", command=lambda: login_func(Login)
)
self.login.grid(row=3, column=2)
self.create_new = ttk.Button(
self,
text="Create New Account",
style="my.TButton",
command=lambda: controller.show_frame(CreateNew),
)
self.create_new.grid(row=4, column=2, pady=10)
self.username.bind("<Return>", login_func)
self.password.bind("<Return>", login_func)
# account creation
class CreateNew(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.label0 = ttk.Label(self, text="New Account")
self.label0.grid(row=0, column=0, padx=40, pady=10)
self.label1 = ttk.Label(self, text="Set Username:", style="my.TLabel")
self.label1.grid(row=1, column=1)
self.username = ttk.Entry(self)
self.username.grid(row=1, column=2)
self.label2 = ttk.Label(self, text="Set Password:", style="my.TLabel")
self.label2.grid(row=2, column=1, padx=5, pady=5)
self.password = ttk.Entry(self)
self.password.grid(row=2, column=2)
def complete_acct(event):
if len(self.username.get()) != 0:
db.add_value(self.username.get(), self.password.get())
self.username.delete(0, tk.END), self.password.delete(0, tk.END)
self.done = ttk.Label(self, text="account created!", style="my.TLabel")
self.done.grid(row=6, column=4)
else:
self.failed = ttk.Label(
self, text="missing required info", style="my.TLabel"
)
self.failed.grid(row=6, column=2)
self.create_button = ttk.Button(
self,
text="Complete New Account",
style="my.TButton",
command=lambda: complete_acct(Login),
)
self.create_button.grid(row=3, column=2, padx=5, pady=5)
self.checkDB = ttk.Button(
self, text="test DB", style="my.TButton", command=lambda: db.check_table()
)
self.checkDB.grid(row=4, column=2)
self.home = ttk.Button(
self,
text="Go to Login",
style="my.TButton",
command=lambda: controller.show_frame(Login),
)
self.home.grid(row=5, column=2, padx=5, pady=5)
# contains tests for adding and viewing
class Userdata(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.textarea = tk.Text(self)
self.textarea.grid(row=1)
def user_select():
db.cursor.execute('SELECT rowid FROM users WHERE username = (?)', (user_id,))
items = db.cursor.fetchall()
for item in items:
print(item)
print('ran')
def add_note(note):
db.cursor.execute("""
INSERT INTO Notes (?,?)""", (1, note,))
# FIXME
self.save = ttk.Button(
self,
text="Save to Account",
style="my.TButton",
command=lambda: add_note(self.textarea.get('1.0', tk.END)),
)
self.save.grid(row=2)
self.view_note = ttk.Button(
self,
text="view note",
style="my.TButton",
command=lambda: print("placeholder: shows saved note to prove functionality"),
)
self.view_note.grid(row=1, column=1)
self.logout = ttk.Button(
self,
text="Logout",
style="my.TButton",
command=lambda: controller.show_frame(Login),
)
self.logout.grid(row=2, column=1)
app = LoginInterface()
app.mainloop()

CLASS MATH -- Need Help getting an Int Value from XY -- Super Lost

Okay, so I am been learning python for 2 weeks and implementing TkInter now, I am trying to make an project where the user can set an Alarm and when the alarm rings the user will hit stop then the program will ask the user some random math questions, I been messing around and got everything up to the Math problem to work, I have a lot of placeholders in place and I am stuck with getting the answer of x and y to return to an INT, I have it made where it will show what x+y will equal and what the user enter but when I run the while loop my program just freezes. I assume its because the answer returns as a Label and that's not an INT, so all my issues are in my Math Class and have been trying for 3 days and cant figure it out. Please anything will be helpful, I tried using the .get method but that also gives me errors.
import tkinter as tk
import time
import datetime
from tkinter import *
from winsound import PlaySound, SND_FILENAME, SND_LOOP, SND_ASYNC
import random
class WakeUpApp(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, minsize=400, weight=1)
container.grid_columnconfigure(0, minsize=250, weight=2)
self.frames = {}
for F in (Alarm, Chooser, Difficulty, Math):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky='nsew')
self.show_frame(Alarm)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
present = datetime.datetime.now()
now = present.strftime("%H:%M:%S")
class Alarm(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
Alarm.hour = tk.StringVar()
Alarm.min = tk.StringVar()
Alarm.sec = tk.StringVar()
hour_a = tk.Entry(self, text=Alarm.hour, width=4).place(x=50, y=50)
min_a = tk.Entry(self, text=Alarm.min, width=4).place(x=70, y=50)
sec_a = tk.Entry(self, text=Alarm.sec, width=4).place(x=90, y=50)
current_time = tk.Label(self, text=f'Current Time: {now}').place(x=0, y=30)
set_time = tk.Label(self, text='Set Time').place(x=0, y=50)
'''
VERY IMPORTANT -- THIS CODE STARTS THE ALARM
setalarm = tk.Button(self, text='Set Alarm', command=lambda: wake())
setalarm.place(x=90, y=90)
'''
setalarm = tk.Button(self, text='Set Alarm', command=lambda: controller.show_frame(Chooser))
setalarm.place(x=90, y=90)
def wake():
alarm_time = f'{Alarm.hour.get()}:{Alarm.min.get()}:{Alarm.sec.get()}'
alarm_clock(alarm_time)
def play_sound(self,):
PlaySound('Sound.wav', SND_FILENAME|SND_LOOP|SND_ASYNC)
def stop_sound(self):
PlaySound(None, SND_FILENAME)
def alarm_clock(alarm_time):
while True:
time.sleep(1)
present = datetime.datetime.now()
now = present.strftime("%H:%M:%S")
print(now)
if now == alarm_time:
break
if now == alarm_time:
play_sound(self)
testbutton = Button(self, text='pls work', command=lambda: stop_sound(self))
testbutton.pack()
class Chooser(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text='Please Choose Your Wake Up Game')
label.pack(pady=50, padx=50)
math = tk.Button(self, text='Math Game',
height=5, width=15,
command=lambda: controller.show_frame(Difficulty))
math.place(x=125, y=75)
guesser = tk.Button(self, text='Guessing Game',
height=5, width=15,
command=lambda: controller.show_frame(Alarm))
guesser.place(x=125, y=175)
class Difficulty(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text='Please Choose Your Difficulty for the Questions')
label.pack(pady=50, padx=50)
level1 = tk.Button(self, text='Level 1 \n ie: 12+17',
height=5, width=15,
command=lambda: controller.show_frame(Math))
level1.place(x=125, y=75)
level2 = tk.Button(self, text='Level 2 \n ie: 12*9',
height=5, width=15,
command=lambda: controller.show_frame(Alarm))
level2.place(x=125, y=175)
level3 = tk.Button(self, text='Level 3 \n ie: 6*7+21',
height=5, width=15,
command=lambda: controller.show_frame(Alarm))
level3.place(x=125, y=275)
class Math(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
x = tk.IntVar()
y = tk.IntVar()
z = tk.IntVar()
ab = tk.IntVar()
x = random.randint(1, 10)
y = random.randint(1, 10)
xy = int(x + y)
problem = tk.Label(self, text=f'{x} + {y}').place(x=0, y=30)
goal = tk.Label(self, text=xy).place(x=0, y=90)
solution = tk.Entry(self, text=z).place(x=0, y=50)
new = tk.Entry(self, text=ab).place(x=0, y=70)
def answer2(self):
py_guess = tk.Label(self, text=ab.get()).place(x=125, y=120)
button2 = tk.Button(self, text='GIVE ME Z PLS', command=lambda: answer())
button2.pack()
button2 = tk.Button(self, text='The Problem', command=lambda: answer2(self))
button2.pack()
def answer():
user_guess = tk.Label(self, text=z.get()).place(x=125, y=100)
level1(user_guess)
def level1(user_guess):
keepGoing = True
while keepGoing:
if (z == xy):
good = tk.Label(self, text='good job').pack()
keepGoing = False
else:
bad = tk.Label(self, text='nope go again').pack()
string_solution = solution.get()
int_solution = int(string_solution)
app = WakeUpApp()
app.mainloop()

Tkinter Multiple GUI

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

Python Tkinter - how to get access to the parent's class dictionary from start window

It tries to display the slider which is responsible for setting the age of logged-in user. The data is downloaded during the user's verification. I want the slider to take the default value of self.controller.fromDB['age'].But also other data such name or email of the user. When trying to use dictionary self.controller.fromDB['age'], key error appears.Unless there is another possibility to solve this problem ?
class FirstApp(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.userInfo = {}
self.connection = myconnutils.getConnection()
self.cursor = self.connection.cursor()
for F in (LoginPage, MainPage):
page_name = F.__name__
frame = F(parent=container, controller=self)
self.frames[page_name] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame("LoginPage")
def __del__(self):
self.connection.close()
def show_frame(self, page_name):
frame = self.frames[page_name]
frame.tkraise()
class LoginPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.cursor= self.controller.cursor
label2 = tk.Label(self, text="Login:")
label2.pack(side="left", fill="x", pady=10)
label2.place(x=310, y=90, in_=self)
self.e1 = tk.Entry(self)
self.e1.pack(side="left", fill="x", pady=10)
self.e1.place(x=370, y=90, in_=self)
label3 = tk.Label(self, text="Password:")
label3.pack(side="left", fill="x", pady=10)
label3.place(x=310, y=120, in_=self)
self.e2 = tk.Entry(self, show="*")
self.e2.pack(side="left", fill="x", pady=10)
self.e2.place(x=370, y=120, in_=self)
button1 = tk.Button(self, text="Login",
command=self._login_btn_clicked,width = 25)
button1.pack()
button1.place(x=310, y=150, in_=self)
def _login_btn_clicked(self):
username = self.e1.get()
password = self.e2.get()
hash = hashlib.sha512()
hash.update(('%s%s' % ('salt', password)).encode('utf-8'))
password_hash = hash.hexdigest()
sql = "Select COUNT(id) AS count,age, from users Where username = %s AND password = %s"
self.cursor.execute(sql, (username,password_hash))
fromDB = self.cursor.fetchall()
if fromDB[0]['count'] > 0:
self.controller.userInfo['age'] = fromDB[0]['age']
self.controller.show_frame("MainPage")
class MainPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text="Main Page", font=controller.title_font)
label.pack()
self.connection = controller.connection
self.cursor = self.controller.cursor
self.w = tk.Scale(self, from_=0, to=200, orient='horizontal')
self.w.pack()
self.w.set(7)
button = tk.Button(self, text="Print",
command=self.funcPrint)
button.pack()
def funcPrint(self):
ee=self.w.get()
print(ee)
print(self.controller.fromDB['age'])
if __name__ == "__main__":
app = FirstApp()
app.geometry('{}x{}'.format(300, 300))
app.mainloop()
As #jasonharper mentions, fromDB is a local variable within _login_btn_clicked() which means that it exists for that scope (and scopes that exists within _login_btn_clicked).
The fact of the matter is that you don't specifically want fromDB; you say in your question that you want access to age and other user data. The other data doesn't exist in fromDB, so getting access to fromDB wouldn't help you there.
You do, however, have another dictionary called userInfo on your controller (FirstApp) which is where you store age and- assumably- where you intend to store stuff like Username, Login Token, etc.
So, just change your code to self.controller.userInfo['age'] and plan on storing/retrieving in that manner for other information.

python tkinter creating a widget outside his frame

I want to create a widget outside his frame, but I don't know what's his master.
this is the structure.
first I created the class of the root. and then 3 classes of frames.
inside the class of the root I put a function. inside the function I created a text widget that should be located in the first one of the 3 frames
I really don't get what I should write as the master of my text widget to locate it in the first frame.
since I am a beginner if you have any advice I'd really appreciate.
thanks for attention here's the code
import tkinter as tk
from tkinter import ttk
from PIL import Image, ImageTk
import datetime
LARGE_FONT = ("VERDANA", 12)
#user's information manager(classes and method)
class person:
def __init__(self, name, birthday, sex):
self.name = name
self.birthday = birthday
self.sex = sex
def age(self, name, birthday):
user = person(name, birthday, "male")
today = datetime.date.today()
print (today.year - self.birthday.year)
#main windows
class deathCalculatorapp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
tk.Tk.wm_title(self, "age calculator app")
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")
# all methods here
def show_frame(self, page_name):
'''Show a frame for the given page name'''
frame = self.frames[page_name]
frame.tkraise()
def calculate(self, name, birthday):
user = person(name, birthday, "male")
text_answer = tk.Text(master = , height=3, width=30)
text_answer.grid(column=1, row=9)
answear_text = ("{name} is {age} years old".format(name=name_entry.get(), age=calculate()))
text_answer.insert(tk.END, answear_text)
print (user.age()
#all of the frames
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
#Labels
label = ttk.Label(self, text="deathcalculatorapp", font=LARGE_FONT)
label.grid(column=1, row=0)
first_label = ttk.Label(self, text = "insert your data")
name_label= tk.Label(self, text = "name", bg="lightblue")
year_label = tk.Label(self, text="year", bg ="lightblue", padx=9)
month_label = tk.Label(self, text= "month", bg = "lightblue", padx=3)
day_label = tk.Label(self, text ="day", bg= "lightblue", padx=11)
first_label.grid(column=1, row=3)
name_label.grid(column=0, row=4)
year_label.grid(column=0, row =5)
month_label.grid(column=0, row =6)
day_label.grid(column=0, row = 7)
#Entries
name_entry = tk.Entry(self, text = "", bg = "lightblue")
year_entry = tk.Entry(self,text = "", bg = "lightblue")
month_entry = tk.Entry(self, text = "", bg= "lightblue")
day_entry = tk.Entry(self, text= "", bg = "lightblue")
name_entry.grid(column=1, row=4)
year_entry.grid(column=1,row=5)
month_entry.grid(column=1, row= 6)
day_entry.grid(column=1, row=7)
#Radiobutton about sex
sexdatum = tk.IntVar()
female= ttk.Radiobutton(self, text="female",variable= sexdatum, value="female")
male=ttk.Radiobutton(self, text="male", variable= sexdatum, value="male")
female.grid(column=2, row=4)
male.grid(column=2, row=5)
#Buttons
calculate_button = ttk.Button(self, text="calculate your lifespawn",
command=lambda: controller.age(name_entry.get(),datetime.date(int(year_entry.get()),int(month_entry.get()),int(day_entry.get()))))
calculate_button.grid(column=1, row=8)
button1 = ttk.Button(self, text="Go to Page One",
command=lambda: controller.show_frame("PageOne"))
button2 = ttk.Button(self, text="Go to Page Two",
command=lambda: controller.show_frame("PageTwo"))
button1.grid(column=0, row=0)
button2.grid(column=0, row=1)
#text
#image
image = Image.open(r"/"
r"Users/tommasomasaracchio/Documents/pythonfolder/kushina4.jpg")
image.thumbnail((500,300), Image.ANTIALIAS)
photo = ImageTk.PhotoImage(image)
Photo_label= ttk.Label(self, image=photo)
Photo_label.image = photo
Photo_label.grid(row= 2, column = 1)
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = ttk.Label(self, text="This is page 1", font=LARGE_FONT)
label.grid(column=0, row=0)
button = ttk.Button(self, text="Go to the start page",
command=lambda: controller.show_frame("StartPage"))
button.grid(column=0, row=0)
class PageTwo(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = ttk.Label(self, text="This is page 2", font=LARGE_FONT)
label.grid(column=0, row=0)
button = ttk.Button(self, text="Go to the start page",
command=lambda: controller.show_frame("StartPage"))
button.grid(column=0, row=0)
if __name__ == "__main__":
app = deathCalculatorapp()
app.mainloop()
It should be master = self.frames['StartPage'].

Categories

Resources