Running another class in the same window using tkinter - python

I'm trying to build my first app using python and tkinter.
I'm stuck where I can't run the content from another class into the same first window.
The first window is a login window, here is the full code of the class:
import tkinter as tk
import sqlite3
from tkinter import *
from gamecontent import Gamecontent
class MainApp(Tk):
def __init__(self):
Tk.__init__(self)
self.title('Word Warrior - Sign In')
self.geometry("650x510")
self.resizable(width=False, height=False)
# Create widgets
self.label_username = tk.Label(self, text="Username")
self.label_password = tk.Label(self, text="Password")
self.entry_username = tk.Entry(self)
self.entry_password = tk.Entry(self, show="*")
self.button_login = tk.Button(self, text="Login", command=self.login)
self.button_createacc = tk.Button(self, text="Create Account", command=self.createacc)
# Place widgets
self.label_username.place(x=200, y=150)
self.label_password.place(x=200, y=200)
self.entry_username.place(x=280, y=152, width=140, height=27)
self.entry_password.place(x=280, y=202, width=140, height=27)
self.button_login.place(x=280, y=242, width=140, height=27)
self.button_createacc.place(x=280, y=282, width=140, height=27)
# Create database and tables and cursor object
self.conn = sqlite3.connect('users.db')
self.c = self.conn.cursor()
self.c.execute("CREATE TABLE IF NOT EXISTS users (username text UNIQUE, password text)")
self.conn.commit()
self.conn.close()
def clear_content(self):
for widget in self.winfo_children():
widget.destroy()
def login(self):
# Get the username and password from the entry widgets
username = self.entry_username.get()
password = self.entry_password.get()
# Fetch username and password from the database
conn = sqlite3.connect('users.db')
c = conn.cursor()
c.execute("SELECT * FROM users WHERE username=? AND password=?", (username, password))
result = c.fetchone()
conn.close()
# Check if the username and password are correct
if result:
# If the login is successful, open a new window with the flashcard game
self.clear_content()
Gamecontent()
else:
# If the login is not successful, display an error message
self.label_message = tk.Label(self, text=" Wrong credentials ")
self.label_message.place(x=285, y=322)
def createacc(self):
# Get the username and password from the entry widgets
username = self.entry_username.get()
password = self.entry_password.get()
# Checks if user is entering an empty username/password while creating
if username == "" or password == "":
self.label_message = tk.Label(self, text=" Can't be empty ")
self.label_message.place(x=290, y=322)
else:
# Connect to the database (or create it if it doesn't exist)
conn = sqlite3.connect('users.db')
c = conn.cursor()
# Create the table if it doesn't exist
c.execute('''CREATE TABLE IF NOT EXISTS users
(username text, password text)''')
# Checks if an account with the same username exists
c.execute("SELECT * FROM users WHERE username = ?", (username,))
if c.fetchone() is None:
c.execute("INSERT INTO users VALUES (?, ?)", (username, password))
conn.commit()
self.label_message = tk.Label(self, text=" Account created ")
self.label_message.place(x=290, y=322)
else:
self.label_message = tk.Label(self, text=" Username exists ")
self.label_message.place(x=290, y=322)
# Close the connection
conn.close()
app = MainApp()
app.mainloop()
The change must be done when the login is correct, exactly in
self.clear_content()
Gamecontent()
The problem is that Gamecontent opens in another window and not into the same window.
Here is the code for Gamecontent class
from tkinter import *
from random import randint
from gamedata import words, count
class Gamecontent(Tk):
def __init__(self):
Tk.__init__(self)
self.title('Word Warrior - Play')
self.geometry("650x510")
self.resizable(width=False, height=False)
def next():
global hinter, hinter_count
# Clear the screen
answer_label.config(text="")
my_entry.delete(0, END)
hint_label.config(text="")
# Reset Hint stuff
hinter = ""
hinter_count = 0
# Create random selection
global random_word
random_word = randint(0, count-1)
# update label with Spanish Word
spanish_word.config(text=words[random_word][0])
def answer():
if my_entry.get().capitalize() == words[random_word][1]:
answer_label.config(text=f"Correct! {words[random_word][0]} is {words[random_word][1]}")
else:
answer_label.config(text=f"Incorrect! {words[random_word][0]} is not {my_entry.get().capitalize()}")
def hint():
global hinter_count
global hinter
if hinter_count < len(words[random_word][1]):
hinter = hinter + words[random_word][1][hinter_count]
hint_label.config(text=hinter)
hinter_count +=1
# Labels
spanish_word = Label(self, text="", font=("Helvetica", 36))
spanish_word.pack(pady=50)
answer_label = Label(self, text="")
answer_label.pack(pady=20)
my_entry = Entry(self, font=("Helvetica", 18))
my_entry.pack(pady=20)
# Create Buttons
button_frame = Frame(self)
button_frame.pack(pady=20)
answer_button = Button(button_frame, text="Answer", command=answer)
answer_button.grid(row=0, column=0, padx=20)
next_button = Button(button_frame, text="Next", command=next)
next_button.grid(row=0, column=1)
hint_button = Button(button_frame, text="Hint", command=hint)
hint_button.grid(row=0, column=2, padx=20)
# Create Hint Label
hint_label = Label(self, text="")
hint_label.pack(pady=15)
# Run next function when program starts
next()
self.mainloop()
I'm stuck with this for a while and can't move forward, I'm not even sure it's possible with tkinter to do so.
I tried clearing the content of the window and start an instance of the second class but it opens in another window.

Change
self.clear_content()
Gamecontent()
to
self.clear_content()
Gamecontent(self)
In gamecontent itself change
class Gamecontent(Tk):
def __init__(self):
Tk.__init__(self)
self.title('Word Warrior - Play')
self.geometry("650x510")
self.resizable(width=False, height=False)
to
class Gamecontent(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
#self.config(bg="white")
self.pack(fill=BOTH, expand=True)
parent.title('Word Warrior - Play')
This makes gamecontent to a frame which packs itself into your main app

Related

How can I set some password length restrictions using python?

Here is where I believe I would put the code for the restrictions
def savePassword():
os.system("Email.py")
if txt.get() == txt1.get():
# encode password for hashing
hashedPassword = hashPassword(txt.get().encode("utf-8"))
# insert masterpassword into database
insert_password = """INSERT INTO masterpassword(password)
VALUES(?) """
cursor.execute(insert_password, [hashedPassword])
sql_command = 'INSERT INTO details (email) VALUES(?) ' # Query
email = txt3.get()
cursor.execute(sql_command, [email])
db.commit()
passwordVault()
else:
lbl2.config(text="Passwords do not match")
i'd like it so that if the password does not reach a length requirement of say 7
Entry widget has validate and validatecommand that can do this job.
Here's an example code:
from tkinter import *
def check(ch):
return len(ch) <= 7 or ch==''
root = Tk()
ent = Entry(root, show='*')
ent.config(validate='key', validatecommand=(root.register(check), "%P"))
ent.pack()
root.mainloop()
update:
from tkinter import *
def savePasswd():
if len(ent.get())>7:
label['text'] = 'saved'
print("saved") # write save stmts here
else:
label['text']="Minimum length 7"
root = Tk()
label = Label(root)
label.pack()
ent = Entry(root, show='*')
ent.pack()
Button(root, text='save password', command=savePasswd).pack()
root.mainloop()

Unable to redirect to register page

When I run my login page and click the sign up button, it does not redirect to the register page but it just maintains at the login page
import register
import pymysql
class Login:
def __init__(self,root):
self.root=root
self.root.title("Scheduling Management System")
self.root.geometry("1350x768+0+0")
self.root.resizable(False,False)
self.txt_user = StringVar()
self.txt_pass = StringVar()
self.bg = ImageTk.PhotoImage(file = "Images/bgimage.jpg")
bg = Label(self.root,image=self.bg).place(x = 0, y= 0, relwidth = 1, relheight = 1)
framelogin = Frame(self.root,bg="white")
framelogin.place(x=450,y=100,height=500,width=700)
title=Label(framelogin,text="Login Here",font=("Arial",30,"bold"),fg="orange",bg="white").place(x=90,y=30)
nexttitle=Label(framelogin,text="Scheduling Staff System",font=("Times New Roman",18,"bold"),fg="orange",bg="white").place(x=90,y=100)
userlabel=Label(framelogin,text="Username",font=("Arial",15,"bold"),fg="gray",bg="white").place(x=90,y=140)
self.txt_user=Entry(framelogin,textvariable = self.txt_user,font=("times new roman",15),bg="lightgray")
self.txt_user.place(x=90,y=170,width=350,height=35)
passlabel=Label(framelogin,text="Password",font=("Arial",15,"bold"),fg="gray",bg="white").place(x=90,y=210)
self.txt_pass=Entry(framelogin,textvariable = self.txt_pass,font=("times new roman",15),show="*",bg="lightgray")
self.txt_pass.place(x=90,y=240,width=350,height=35)
forget=Button(framelogin,text="Forgot Password",bg="white",fg="orange",font=("trebuchet ms",12)).place(x=90,y=305)
reglabel=Label(framelogin,text="Don't Have an Account?",font=("trebuchet ms",12,"bold"),fg="orange",bg="white").place(x=320,y=310)
registerbutton=Button(framelogin,text="Sign Up",command=register,bg="white",fg="orange",font=("trebuchet ms",12)).place(x=510,y=305)
loginbutton=Button(framelogin,text="Login",command=self.login,fg="white",bg="orange",font=("sans serif ms",20)).place(x=90,y=350,width="100",height="40")
def login(self):
if self.txt_user.get() == "" or self.txt_pass.get() == "":
messagebox.showerror("Error", "Please fill up all fields!")
root = Tk()
obj = Login(root)
root.mainloop()
Here is my register page
from tkinter import *
from tkinter import ttk, messagebox
import PIL
import pymysql
from PIL import ImageTk
from PIL import Image
class Register:
def __init__(self, root):
self.root = root
self.root.title("Registration Page")
self.root.geometry("1350x768+0+0")
self.root.config(bg="light blue")
self.bg = ImageTk.PhotoImage(file="Images/bgimage.jpg")
bg = Label(self.root,image=self.bg).place(x = 0, y= 0, relwidth = 1, relheight = 1)
frame1=Frame(self.root,bg="white")
frame1.place(x=450,y=100,width=700,height=600)
title=Label(frame1,text="Please enter your information here",font=("trebuchet ms",20,),bg="white",fg="black").place(x=50, y=30)
fname=Label(frame1,text="First Name",font=("times new roman",15,"bold"),bg="white",fg="black").place(x=50, y=100)
self.text_fname=Entry(frame1,font=("arial",15,),bg="lightgray")
self.text_fname.place(x=50, y=130, width=250)
lname=Label(frame1,text="Last Name",font=("times new roman",15,"bold"),bg="white",fg="black").place(x=370, y=100)
self.text_lname=Entry(frame1,font=("arial",15,),bg="lightgray")
self.text_lname.place(x=370, y=130, width=250)
contact=Label(frame1,text="Contact Number",font=("times new roman",15,"bold"),bg="white",fg="black").place(x=50, y=170)
self.text_contact=Entry(frame1,font=("arial",15,),bg="lightgray")
self.text_contact.place(x=50, y=200, width=250)
email=Label(frame1,text="Email Address",font=("times new roman",15,"bold"),bg="white",fg="black").place(x=370, y=170)
self.text_email=Entry(frame1,font=("arial",15,),bg="lightgray")
self.text_email.place(x=370, y=200, width=250)
question=Label(frame1,text="Security Question",font=("times new roman",15,"bold"),bg="white",fg="black").place(x=50, y=240)
self.cmbquestion=ttk.Combobox(frame1,font=("times new roman",13),state='readonly',justify=CENTER)
self.cmbquestion['values']=("Select","Your First Car","Your Mothers First Name", "Your Best Friend Name")
self.cmbquestion.place(x=50, y=270, width=250)
self.cmbquestion.current(0)
answer=Label(frame1,text="Answer",font=("times new roman",15,"bold"),bg="white",fg="black").place(x=370, y=240)
self.text_answer=Entry(frame1,font=("arial",15,),bg="lightgray")
self.text_answer.place(x=370, y=270, width=250)
pwd=Label(frame1,text="Password",font=("times new roman",15,"bold"),bg="white",fg="black").place(x=50, y=310)
self.text_pwd=Entry(frame1,font=("arial",15,),show="*",bg="lightgray")
self.text_pwd.place(x=50, y=340, width=250)
cfmpwd=Label(frame1,text="Confirm Password",font=("times new roman",15,"bold"),bg="white",fg="black").place(x=370, y=310)
self.text_cfmpwd=Entry(frame1,font=("arial",15,),show="*",bg="lightgray")
self.text_cfmpwd.place(x=370, y=340, width=250)
self.btn= ImageTk.PhotoImage(file="images/register.png")
btn = Button(frame1,image=self.btn, bd=0, command = self.registerdata,cursor = "hand2").place(x=50, y = 420)
def registerdata(self):
if self.text_fname.get()=="" or self.text_lname.get()=="" or self.text_contact.get()=="" or self.text_email.get()=="" or self.cmbquestion.get()=="Select" or self.text_pwd.get()=="" or self.text_cfmpwd.get()=="":
messagebox.showerror("Error","All fields are required!",parent=self.root)
elif self.text_pwd.get()!=self.text_cfmpwd.get():
messagebox.showerror("Error","Passwords must be the same!",parent=self.root)
else:
try:
con=pymysql.connect(host="localhost",user="root",password="",database="employee")
cur=con.cursor()
cur.execute("select * from employeelist where email=%s", self.text_email.get())
row=cur.fetchone()
print(row)
if row!=None:
messagebox.showerror("Error","User Already Exists. Please Register With a New Email",parent=self.root)
else:
cur.execute("insert into employeelist (fname,lname,contact,email,question,answer,password) values(%s,%s,%s,%s,%s,%s,%s)",
(self.text_fname.get(),self.text_lname.get(),self.text_contact.get(),self.text_email.get(),self.cmbquestion.get(),self.text_answer.get(),self.text_pwd.get()))
con.commit() #do changes to database
con.close()
messagebox.showinfo("Success","Registration Successful",parent=self.root)
except Exception as ex:
messagebox.showerror("Error",f"Error due to: {str(ex)}",parent=self.root)
root = Tk()
obj = Register(root)
root.mainloop()
I have inserted the action for the button as command = register but it is still not redirecting to the register page. Is there any error with my command function?
Better move the main block code inside register.py in a function:
class Register:
...
def RegisterForm():
win = Toplevel()
obj = Register(win)
Then you can use this function inside the login page:
import register
...
class Login:
def __init__(self):
...
Button(framelogin,text="Sign Up",command=self.register,bg="white",fg="orange",font=("trebuchet ms",12)).place(x=510,y=305)
...
def register(self):
register.RegisterForm()
Here I made a registration frame on the main window/frame and raised it above all existing frames.Then when submit button is pressed that frame gets destroyed.
class login:
def __init__(self):
button=tk.Button(command=self.register)
def register(self):
f1=tk.Frame(root)
f1.tkraise()
boo=tk.Button(text='submit',command=f1.destroy)

function call from a function to a function within a class fails

I'm trying to setup a program where my tkinter GUI functions are in a class and my database functions are in another class. I have a function external to both classes that fails when I try to call a function within the DB class. Can you help me resolve this error? Should both my GUI and any database be in separate functions or is that a poor design. The attached code is a stripped down version to illustrates my issue. Clicking the "View all" button generates the error.
import sqlite3
from tkinter import *
from tkinter import messagebox
class DB:
def __init__(self):
self.conn = sqlite3.connect("mybooks.db")
self.cur = self.conn.cursor()
self.cur.execute(
"CREATE TABLE IF NOT EXISTS book (id INTEGER PRIMARY KEY, title TEXT, author TEXT, isbn INTEGER)")
self.conn.commit()
def __del__(self):
self.conn.close()
def view(self):
self.cur.execute("SELECT * FROM book")
rows = cur.fetchall()
return rows
def view_command():
# there is a problem with the next line
# when rows=DB.view() error is TypeError: view() missing 1 required positional argument: 'self'
# when rows=DB.view(self) error is NameError: name 'self' is not defined
rows=DB.view(self)
for row in rows:
print(row)
class App_GUI(): # create the main window
def __init__(self, master):
self.master = master
self.master.title("My Books")
self.master.l1 = Label(self.master, text="Title")
self.master.l1.grid(row=0, column=0)
self.master.l2 = Label(self.master, text="Author")
self.master.l2.grid(row=0, column=2)
self.master.l3 = Label(self.master, text="ISBN")
self.master.l3.grid(row=1, column=0)
self.master.title_text = StringVar()
self.master.e1 = Entry(self.master, textvariable=self.master.title_text)
self.master.e1.grid(row=0, column=1)
self.master.author_text = StringVar()
self.master.e2 = Entry(self.master, textvariable=self.master.author_text)
self.master.e2.grid(row=0, column=3)
self.master.isbn_text = StringVar()
self.master.e3 = Entry(self.master, textvariable=self.master.isbn_text)
self.master.e3.grid(row=1, column=1)
self.master.list1 = Listbox(self.master, height=6, width=35)
self.master.list1.grid(row=2, column=0, rowspan=6, columnspan=2)
self.master.sb1 = Scrollbar(self.master)
self.master.sb1.grid(row=2, column=2, rowspan=6)
self.master.list1.configure(yscrollcommand=self.master.sb1.set)
self.master.sb1.configure(command=self.master.list1.yview)
self.master.b1 = Button(self.master, text="View all", width=12, command=view_command)
self.master.b1.grid(row=2, column=3)
self.master.b6 = Button(self.master, text="Close", width=12, command=self.master.destroy)
self.master.b6.grid(row=7, column=3)
return
###############################
# Program Main #
###############################
def main():
db = DB()
root = Tk()
def on_closing():
dd = db
if messagebox.askokcancel("Quit", "Do you want to close the application"): # ask the user if he/she wants to close the application
root.destroy()
del dd
root.protocol("WM_DELETE_WINDOW", on_closing) # catch the user closing the window
app = App_GUI(root) # creation of an instance
root.mainloop() # tkinter mainloop
if __name__ == '__main__':
main()
````
You need to pass db to App_GUI and then on to the function:
def view_command(db):
rows = db.view()
for row in rows:
print(row)
class App_GUI(): # create the main window
def __init__(self, master, db):
# other stuff elided ...
self.master.b1 = Button(self.master, text="View all", width=12, command=lambda : view_command(db))
...
def main():
db = DB()
# other stuff elided
app = App_GUI(root, db)
edit: forgot to remove self.
I figured it out! In addition to your changes, I had to remove 'self' from rows=db.view(). Thanks for your help! Revised code:
import sqlite3
from tkinter import *
from tkinter import messagebox
class DB:
def __init__(self):
self.conn = sqlite3.connect("mybooks.db")
self.cur = self.conn.cursor()
self.cur.execute(
"CREATE TABLE IF NOT EXISTS book (id INTEGER PRIMARY KEY, title TEXT, author TEXT, isbn INTEGER)")
self.conn.commit()
def __del__(self):
self.conn.close()
def view(self):
self.cur.execute("SELECT * FROM book")
rows = self.cur.fetchall()
return rows
def view_command(db):
rows=db.view()
for row in rows:
print(row)
class App_GUI(): # create the main window
def __init__(self, master, db):
self.master = master
self.master.title("My Books")
self.master.l1 = Label(self.master, text="Title")
self.master.l1.grid(row=0, column=0)
self.master.l2 = Label(self.master, text="Author")
self.master.l2.grid(row=0, column=2)
self.master.l3 = Label(self.master, text="ISBN")
self.master.l3.grid(row=1, column=0)
self.master.title_text = StringVar()
self.master.e1 = Entry(self.master, textvariable=self.master.title_text)
self.master.e1.grid(row=0, column=1)
self.master.author_text = StringVar()
self.master.e2 = Entry(self.master, textvariable=self.master.author_text)
self.master.e2.grid(row=0, column=3)
self.master.isbn_text = StringVar()
self.master.e3 = Entry(self.master, textvariable=self.master.isbn_text)
self.master.e3.grid(row=1, column=1)
self.master.list1 = Listbox(self.master, height=6, width=35)
self.master.list1.grid(row=2, column=0, rowspan=6, columnspan=2)
self.master.sb1 = Scrollbar(self.master)
self.master.sb1.grid(row=2, column=2, rowspan=6)
self.master.list1.configure(yscrollcommand=self.master.sb1.set)
self.master.sb1.configure(command=self.master.list1.yview)
self.master.b1 = Button(self.master, text="View all", width=12, command=lambda : view_command(db))
self.master.b1.grid(row=2, column=3)
self.master.b6 = Button(self.master, text="Close", width=12, command=self.master.destroy)
self.master.b6.grid(row=7, column=3)
return
###############################
# Program Main #
###############################
def main():
db = DB()
root = Tk()
def on_closing():
dd = db
if messagebox.askokcancel("Quit", "Do you want to close the application"): # ask the user if he/she wants to close the application
root.destroy()
del dd
root.protocol("WM_DELETE_WINDOW", on_closing) # catch the user closing the window
app = App_GUI(root, db) # creation of an instance
root.mainloop() # tkinter mainloop
if __name__ == '__main__':
main()

Multiple GUI with Tkinter

I am using Python 3.x, and I'm trying to fetch Dataset records and display them in an extra Window. I'm a bloody beginner and currently I don't see my error. I've checked multiple threads but didn't get the solution. Debugging isn't helping me either.
Here's my approach:
import sqlite3
from tkinter import *
class Overview():
def __init__(self,master):
self.master = master
self.master.geometry('170x110+100+200')
self.master.title('Welcome!')
self.button1 = Button(self.master, text="Show dataset", fg='green', command=self.gotoMenu).grid(
row=1, column=1)
def gotoMenu(self):
# This is the Dataset GUI#
root2 = Toplevel(self.master)
myGUI = Menu(root2)
def main():
root = Tk()
overviewGUI = Overview(root)
root.mainloop()
if __name__ == '__main__':
main()
class Menu:
def __init__(self,master):
# This is the Dataset GUI#
self.connection = sqlite3.connect('test.db')
print("Opened database successfully")
self.cur = self.connection.cursor()
self.master = master
self.master.title('Dataset')
self.master.geometry("320x240")
print("GUI created")
self.dateLabel = Label(self.master, text="Date", width=10)
self.dateLabel.grid(row=0, column=0)
self.BMILabel = Label(self.master, text="Name", width=10)
self.BMILabel.grid(row=0, column=1)
self.stateLabel = Label(self.master, text="ID", width=10)
self.stateLabel.grid(row=0, column=2)
self.insertDS('random')
self.showallrecords()
def showallrecords(self):
data = self.readfromdatabase()
for index, dat in enumerate(data):
Label(self.master, text=dat[2]).grid(row=index + 1, column=0)
Label(self.master, text=dat[1]).grid(row=index + 1, column=1)
Label(self.master, text=dat[0]).grid(row=index + 1, column=2)
def readfromdatabase(self):
self.cur.execute("SELECT * FROM LOGGING")
return self.cur.fetchall()
def createTable(self):
try:
self.connection.execute(
"CREATE TABLE LOGGING(ID INTEGER PRIMARY KEY AUTOINCREMENT,NAME TEXT NOT NULL, TIMESTAMP DATE DEFAULT (datetime('now','localtime')));")
print("Table created successfully")
except:
print("Table already exists")
def insertDS(self, name):
self.connection.execute("INSERT INTO LOGGING (NAME) \
VALUES (?);", [name])
self.connection.commit()
print("Records created successfully")
My Application should start with the "Overview" GUI, on button click I want to see all fetched Datasets from "Menu" Class.
However, after clicking the button the next window is empty and has the title "Welcome" which should be "Dataset"
UPDATE:
I am getting no error, BUT my fetched results won't show in the 2nd Window, and the title isn't self.master.title('Dataset') as initialized in class Menu.
I feel like it's just creating some empty Window without even looking in my Menu Class?
Solution:
python className not defined NameError
Somehow(can't explain why) when I moved the ´name´ block down with the def (even though indentions were right) it worked.
You have overloaded Menu, change your class name by an another name.
And don't use import *

Inserting user and password with SQLITE/PYTHON

Working on a group program that has users and passwords. We are trying to insert our users and passwords via python to sqlite. But atm we are only sending blank data before our graphic window pops up with a button that is supposed to send the data. We have tried different variations found on multiple websites but nothing seems to work.
from tkinter import *
import sqlite3
import sys
conn = sqlite3.connect('indexCards.db')
cur = conn.cursor()
users ={}
def addUser(entUsername, entPassword):
#global entUsername, entPassword
NAME = entUsername.get()
PASSWORD = entPassword.get()
print("add User") #this is testing only
print(NAME, PASSWORD) # this is testing to see the passed variable
//
//This is where we are having the issues
conn.executemany('INSERT INTO USER(NAME,PASSWORD)\
VALUES (? ,?);', [(NAME,PASSWORD)])
conn.commit();
return (NAME, PASSWORD)
def makeWindow():
global entUsername, entPassword
window = Tk()
window.title('Add New User')
lblInst = Label(window, text = "Create your account here:", font=("Helvetica",16))
lblInst.pack()
lblUsername = Label(window, text="Please enter a username: ")
entUsername = Entry(window)
lblUsername.pack()
entUsername.pack()
lblPassword = Label(window, text="Please enter a password: ")
entPassword = Entry(window)
lblPassword.pack()
entPassword.pack()
btn = Button(window, text="Create", command=addUser(entUsername, entPassword))
btn.pack()
print (addUser(entUsername, entPassword))
print('entUsername', 'entPassword')
#window.mainloop()
return window
#if __name__ == '__main__':
# main():
window = makeWindow()
window.mainloop()
The problem is that you're calling the function immediately, before the user has a chance to enter any data.
See Why is Button parameter “command” executed when declared?
The reason it invokes the method immediately and pressing the button does nothing is that addUser(entUsername, entPassword) is evaluated and its return value is attributed as the command for the button. So if addUser prints something to tell you it has run and returns None, you just run addUser to evaluate its return value and given None as the command for the button.
To have buttons to call functions with different arguments you can use global variables, although I can't recommend it:
import sqlite3
from tkinter import *
conn = sqlite3.connect('indexCards.db')
cur = conn.cursor()
users = {}
cur = conn.cursor()
cur.execute('''
Create table if not exists USER(NAME varchar(100), PASSWORD varchar(100))
''')
def addUser():
NAME = entUsername.get()
PASSWORD = entPassword.get()
print("add User") # this is testing only
print(NAME, PASSWORD) # this is testing to see the passed variable
# This is where we are having the issues
conn.executemany('INSERT INTO USER(NAME,PASSWORD) VALUES (? ,?);', [(NAME, PASSWORD)])
conn.commit()
return (NAME, PASSWORD)
def makeWindow():
global entUsername
global entPassword
window = Tk()
window.title('Add New User')
lblInst = Label(window, text="Create your account here:", font=("Helvetica", 16))
lblInst.pack()
lblUsername = Label(window, text="Please enter a username: ")
entUsername = Entry(window)
lblUsername.pack()
entUsername.pack()
lblPassword = Label(window, text="Please enter a password: ")
entPassword = Entry(window)
lblPassword.pack()
entPassword.pack()
btn = Button(window, text="Create", command=addUser)
btn.pack()
print(addUser())
window.mainloop()
return window
window = makeWindow()
If you don't want to create global then you can pass the function with multiple arguments to an anonymous function i.e lambda function
btn = Button(window, text="Create", command= lambda : addUser(entUsername, entPassword))

Categories

Resources