How can I run this code without using global variables? - python

(to make the error show you have to press the sign up button)Bare in mind I consider myself to be at a beginner level of coding. I'm doing a project for a for a controlled assessment in school and its for an imaginary guild and I have to create an interface that has a login/register system, an invoice system and an order system. These variables were global variables before and I was trying to figure out how to run the same code without having to make them global. I was told that use parameters and this "TypeError: FSSignup() missing 3 required positional arguments: 'eUsername', 'ePassword', and 'signupPage'" showed up.
here's my code:
from tkinter import *
import os
details = 'tempfile.temp' # sets variable details as tempfile
def signup(): # signup subroutine
signupPage = Tk() # makes empty signup window
signupPage.geometry("450x400") # sets size of window 500 pixels by 300
signupPage.title("Signup for The Guild of Ceramic Arts") # adds a title to the window
introL = Label(signupPage, text="Please enter your details: ", font=("Arial", 15)) # heading
introL.place(x=105, y=10)
userL = Label(signupPage, text="New Username: ", font=("Arial", 14)) # user's detail's labels
pwL = Label(signupPage, text="New Password: ", font=("Arial", 14))
userL.place(x=20, y=50)
pwL.place(x=20, y=80)
eUsername = Entry(signupPage, font=("Arial", 14)) # user's detail's entries
ePassword = Entry(signupPage, font=("Arial", 14), show='*')
eUsername.place(x=170, y=50) # Places entries for details
ePassword.place(x=170, y=80)
# adds signup button and command runs the subroutine named 'FSSignup' short for file save sign up
signupB = Button(signupPage, text="Signup", font=("Arial", 12), command=FSSignup)
signupB.place(x=180, y=360)
mainloop()
def FSSignup(eUsername, ePassword, signupPage):
with open(details, 'w') as f:
f.write(eUsername.get())
f.write('\n')
f.write(ePassword.get())
f.write('\n')
f.write(eForename.get())
f.write('\n')
f.write(eSurname.get())
f.write('\n')
f.write(eEmail.get())
f.write('\n')
f.write(ePhoneNum.get())
f.write('\n')
f.write(eAddress.get())
f.write('\n')
f.write(eCity_Town.get())
f.write('\n')
f.write(eCounty.get())
f.close()
signupPage.destroy()
login()
def login():
loginPage = Tk()
loginPage.geometry("400x200")
loginPage.title("Login for the Guild of Ceramic Arts")
headingL = Label(loginPage, text="Please login: ", font=("Arial", 15))
headingL.place(x=140, y=20)
userL = Label(loginPage, text="Username: ", font=("Arial", 14))
passwordL = Label(loginPage, text="Password: ", font=("Arial", 14))
userL.place(x=20, y=50)
passwordL.place(x=20, y=80)
eUser = Entry(loginPage, font=("Arial", 14))
epw = Entry(loginPage, font=("Arial", 14), show='*')
eUser.place(x=120, y=50)
epw.place(x=120, y=80)
loginB = Button(loginPage, text='Login', font=("Arial", 12), command=checkLogin)
loginB.place(x=130, y=120)
delUserB = Button(loginPage, text='Delete User', fg='red', command=delUser, font=("Arial", 12))
delUserB.place(x=190, y=120)
mainloop()
def checkLogin(eUser, epw):
with open(details) as f:
data = f.readlines()
uname = data[0].rstrip()
pword = data[1].rstrip()
if eUser.get() == uname and epw.get() == pword:
return mainMenu()
else:
r = Tk()
r.title('error')
r.geometry('150x50')
rlbl = Label(r, text='\n Invalid Login')
rlbl.pack()
r.mainloop()
def delUser(loginPage):
os.remove(details) # Removes the file
loginPage.destroy() # Destroys the login window
signup() # And goes back to the start
def mainMenu():
pass
signup()

Put your code in main function. This way you can avoid using any global variables.

Related

How am i able to Display every try another Password (tkinter Entry Field)

I created a Tool which allows me to display a Password in a Tkinter Entryfield.
The Goal is: to get every Button click a another Password displayed.
The Problem is (i think) that i dont clear the Variable at some point and execute the Code which creates the Password again to display a new Password. With this Script i only get the same Password displayed
How should i do it?
import customtkinter
from tkinter import *
import secrets
import string
class EasyPass(customtkinter.CTk):
def __init__(self):
super().__init__()
# Form/GUI
self.title("EasyPass")
self.geometry(f"{300}x{100}")
self.resizable(False,False)
# GuiWidgets
self.label = customtkinter.CTkLabel(master=self,
text="EasyPass v1" ,
width=120,
height=25,
corner_radius=8)
self.label.place(relx=0.30, rely=0.045,)
self.pass_creator_button = customtkinter.CTkButton(master=self,
width=100,
height=50,
border_width=0,
corner_radius=8,
text="Password Creator",
command=self.pass_creator)
self.pass_creator_button.place(relx=0.03, rely=0.3)
self.pass_checker_button = customtkinter.CTkButton(master=self,
width=100,
height=50,
border_width=0,
corner_radius=8,
fg_color= "grey",
text="Password Checker",
command=self.pass_check)
self.pass_checker_button.place(relx=0.557, rely=0.3)
def pass_creator(self):
def fill_password(password):
passEntry.delete(0, END)
passEntry.insert(0, password)
alphabet = string.ascii_letters + string.digits + "#$!%*?&'/"
password = ''.join(secrets.choice(alphabet) for i in range(10))
window = customtkinter.CTkToplevel(self)
window.geometry("300x150")
window.title("Password Creator")
# create label on CTkToplevel window
label = customtkinter.CTkLabel(window, text="Create your Password")
label.place(relx=0.28, rely=0.03)
#create Entry Field to display created password
passEntry = customtkinter.CTkEntry(window, placeholder_text="",
justify='center', text_color="#DDE6E8", width=200,
text_font=("Segoe UI", 15, "bold"))
passEntry.pack( padx=5, pady=30)
# Button to create the password
pass_creator_button1 = customtkinter.CTkButton(window,
width=100,
height=50,
border_width=0,
corner_radius=8,
text="Create Password",
command=lambda: fill_password(f"{password}"))
pass_creator_button1.place(relx=0.30, rely=0.5)
def pass_check(self):
pass
if __name__ == "__main__":
app = EasyPass()
app.mainloop()
Thanks for every help

Tkinter button - Replacing old info with new when pressed

Need help solving this problem, I'm a beginner going crazy over this. Each time I press "pingButton1" I want the "pingResult1" to refresh the information insteed of adding new every time I press it. It's a simple "check if ping is good" program.
Any suggestions?
stacking
I've tried using google but nothing is working for me.
from tkinter import *
import os
import subprocess
from time import sleep
menu = Tk()
menu.title("Panel")
menu.geometry("250x380+700+500")
menu.resizable(0, 0)
menu.configure(background="#0d335d")
def close():
screen.destroy()
def pingWindow1():
global ip1
global pingButton1
global screen
screen = Toplevel(menu)
screen.title("Ping Windows")
screen.geometry("300x250+650+300")
screen.configure(background="#0d335d")
blank = Label(screen, bg="#0d335d", text="")
blank.pack()
ip1 = Entry(screen, width=20, bg="white")
ip1.pack()
blank1 = Label(screen, bg="#0d335d", text="")
blank1.pack()
pingButton1 = Button(screen, text="Ping away..", width="20", bg="#e5e5e5", height="2", borderwidth=2, relief="ridge", command=pingResult1)
pingButton1.pack()
close_ping = Button(screen, text="Close", width="20", bg="#e5e5e5", height="2", borderwidth=2, relief="ridge", command=close)
close_ping.pack()
blank2 = Label(screen, text="", bg="#0d335d")
blank2.pack()
screen.bind('<Escape>', lambda _: close())
def pingResult1():
global pingIP1
pingIP1 = ip1.get()
try:
overall_mgm()
except:
return False
try:
overall_mgm_RO()
except:
return False
done = Label(screen, text="Completed").pack()
def overall_mgm():
response = os.system("ping -c 1 sekiiws00"+pingIP1)
if response is not 0:
fail = Label(screen, bg="black", fg="red", text="KI FAILED").pack()
else:
success = Label(screen, bg="black", fg="green", text="KI SUCCESS").pack()
def overall_mgm_RO():
response = os.system("ping -c 1 seroiws00"+pingIP1)
if response is not 0:
fail = Label(screen, bg="black", fg="red", text="RO FAILED").pack()
else:
success = Label(screen, bg="black", fg="green", text="RO SUCCESS").pack()
# Widget
option = Button(menu, text="Ping IP", width="20", bg="#e5e5e5",height="2", borderwidth=2, relief="ridge", command=pingWindow1)
# Out
option.pack()
menu.mainloop()
I'm guessing I need something like this
if pingButton1 clicked more than once
refresh current Labels( fail & success)
def pingResult1():
global pingIP1
pingIP1 = ip1.get()
try:
overall_mgm()
except:
return False
try:
overall_mgm_RO()
except:
return False
done = Label(screen, text="Completed").pack()
with this demo you can change button's text (for example) when pressed.
import tkinter
from functools import partial
# partial is good for passing `function` and `its args`
def button_command(button):
# for example
button.config(text="another value")
# creating new button
# root is whatever you want
button = tkinter.Button(root, text="something")
# add command to button and passing `self`
button.config(command=partial(button_command, button))
button.pack()
adapt this example to your code and you are good to go.

How to add email to the screen?

I have this code, the problem is that when I finish the program and start again, it does not save the email on the screen, only in email.txt.
How can I add the email and password on the screen, being that even when I restart the file the email still appears on the screen, not only in email.txt?
from tkinter import *
from tkinter import messagebox
import tkinter.messagebox
roots = Tk()
roots.title("Email's save")
roots.geometry("500x500")
e = Entry(roots)
e.grid(row=0, column=1)
e.focus_set()
p = Entry(roots, show="*")
p.grid(row=1, column=1)
p.focus_set()
textEmail = StringVar()
textPassword = StringVar()
def callback():
textEmail.set(textEmail.get() + e.get() + "\n")
textPassword.set(textPassword.get() + p.get() + "\n")
def cleargrid():
textEmail.set("")
textPassword.set("")
def delete():
answer = tkinter.messagebox.askquestion('Delete', 'Are you sure you want to delete this entry?')
if answer == 'yes':
cleargrid()
def save():
email_info = e.get()
password_info = p.get()
file = open("emails.txt", "a")
file.write(email_info)
file.write("\n")
file.write(password_info)
file.write("\n")
file.write("=" * 20)
file.close()
def EmailPassword():
email = Label(roots, text="Email: ", font=('Courier', 14))
email.grid(row=0, sticky=W)
passoword = Label(roots, text="Password: ", font=('Courier', 14))
passoword.grid(row=1, sticky=W)
saved_email = Label(roots, text="Saved Email", font=('Courier', 14))
saved_email.grid(row=15, column=0)
saved_password = Label(roots, text="Password", font=('Courier', 14))
saved_password.grid(row=15, column=15)
write_email = Label(roots, textvariable=textEmail, font=('Courier', 14))
write_email.grid(row=20, column=0)
write_password = Label(roots, textvariable=textPassword, font=('Courier', 14))
write_password.grid(row=20, column=15)
btn_save = Button(roots, text="Save", command= lambda:[callback(), save()])
btn_save.grid(row=10, column=2, sticky=W)
btn_del = Button(roots, text="X", fg="red", command=delete)
btn_del.grid(row=60, column=20)
roots.mainloop()
EmailPassword()
Delete your current 'emails.txt'. It isn't formatted properly for the below to work.
Change save to this. Note the \n after your =*20
def save():
with open("emails.txt", "a") as f:
f.write(f'{e.get()}\n{p.get()}\n{"="*20}\n')
Add this function
def get_emails():
try:
with open("emails.txt", "r") as f:
for i, line in enumerate(filter(lambda t: t != f'{"="*20}\n', f.readlines())):
if not i%2:
textEmail.set(f'{textEmail.get()}{line}')
else:
textPassword.set(f'{textPassword.get()}{line}')
except FileNotFoundError:
pass
Add this line right before roots.mainloop()
get_emails()
aside:
Are you really going to store non-encrypted email and password information in a text file?
In order for the email address to appear at the beginning, you have to get that information from the file. Just add another function that opens the file (if present), reads the address and sets the variable textEmail
def set_email():
try:
file = open("emails.txt", "r")
emails = file.readlines()
last_address = emails[-2][:-1] # line before last line without the line break
file.close()
textEmail.set(last_address)
except:
pass ## There was no file "emails.txt"
If you call this function after the variable textEmail is defined, you will have the address when the window is loaded.

Why my pickle database that is in my game doesnt work

I have mini-program, in which You can registrant and start play game. My pickle database doesnt work. And I cant understand what I have done wrong. To create an account in my program you must press on the registration button, then you must press the sign-in button and enter the username, and the password.
import tkinter as tk
import sys
import pyttsx3
import pickle
import time
import smtplib
import string
# Personal office of user
class PersonalOffice:
def __init__(self, username, mail, best_score):
self.username = username
self.mail = mail
self.best_score = best_score
def render(self, master):
personal_office_label = tk.Label(
master=master,
text="Your name is: " + str(self.username),
pady=90,
font=('Arial', 16)
)
personal_office_label.pack()
username_label = tk.Label(
master=master,
text="Your name is: " + str(self.username),
pady=105,
font=('Arial', 14)
)
username_label.pack()
mail_label = tk.Label(
master=master,
text="Your mail is: " + str(self.mail),
pady=110,
font=('Arial', 14)
)
mail_label.pack()
best_score_label = tk.Label(
master=master,
text="Your best score is: " + str(self.best_score),
pady=115,
font=('Arial', 14)
)
best_score_label.pack()
""" bd variables """
# name of user
username_reg = ""
# mail of user
mail_reg = ""
# password of user
password_reg = ""
# sign in username and password
username_s, password_s = "", ""
engine = pyttsx3.init()
def speak(text):
engine.say(text)
engine.runAndWait()
def Start():
pass
def Quit():
sys.exit()
def CreateAccount():
global username_reg, mail_reg, password_reg
db = {
"username": username_reg.get(),
"mail": mail_reg.get(),
"password": password_reg.get(),
"best_score": 0
}
file = open("db/users.pkl", "wb")
pickle.dump(db, file)
file.close()
now_signin = tk.Toplevel()
now_signin.geometry("540x100")
now_signin.overrideredirect(True)
now_signin.resizable(width=False, height=False)
text = tk.Label(now_signin, text="Now, as you have account you can sign in, or sign out", font=('Arial', 14))
text.pack()
def quit_toplevel():
now_signin.destroy()
quit_btn_toplevel = tk.Button(now_signin, text="Quit", background="#fff",
padx="20", pady="8", font=('Arial', 16), command=quit_toplevel)
quit_btn_toplevel.place(relx=.5, rely=.2, anchor="c", height=30, width=130)
def SignAccount():
global username_s, password_s
file = open("db/users.pkl", "rb")
print(pickle.load(file))
for i in pickle.load(file):
if i["username"] == username_s.get() \
and i["password"] == password_s.get():
reg_btn.destroy()
signin_btn.destroy()
HOST = "mySMTP.server.com"
SUBJECT = "SnakeBoom"
TO = i["mail"]
FROM = "arthurtopal342#gmail.com"
text = "Success! You have sign in your account in SnakeBoom. Now you can remember your best result. \n\n To contact with write arthurtopal342#gmail.com. \n Funny game!"
BODY = "\r\n".join((
"From: %s" % FROM,
"To: %s" % TO,
"Subject: %s" % SUBJECT,
"",
text
))
server = smtplib.SMTP(HOST)
server.sendmail(FROM, [TO], BODY)
server.quit()
# create personal office of current user
file.close()
def Reg():
global username_reg, mail_reg, password_reg
reg = tk.Tk()
reg.geometry("500x400")
reg.title("Create new account")
reg.resizable(width=False, height=False)
reg_name = tk.Label(reg, text="Registration", pady=60, font=('Arial', 18))
reg_name.pack()
ure = tk.Label(reg, text="Enter username", font=('Arial', 12))
ure.pack()
username_reg = tk.StringVar()
username_regE = tk.Entry(reg, textvariable=username_reg, width=40)
username_regE.pack()
mre = tk.Label(reg, text="Enter mail", font=('Arial', 12))
mre.pack()
mail_reg = tk.StringVar()
mail_regE = tk.Entry(reg, textvariable=mail_reg, width=40)
mail_regE.pack()
pre = tk.Label(reg, text="Enter password", font=('Arial', 12))
pre.pack()
password_reg = tk.StringVar()
password_regE = tk.Entry(reg, textvariable=password_reg, width=40)
password_regE.pack()
ready_reg = tk.Button(reg, text="Registration ready", background="#fff", padx="20", pady="8", font=('Arial', 16), command=CreateAccount)
ready_reg.place(relx=.5, rely=.8, anchor="c", height=30, width=190)
reg.mainloop()
def SignIn():
global username_s, password_s
reg = tk.Tk()
reg.geometry("500x400")
reg.title("Sign in existed account")
reg.resizable(width=False, height=False)
signin_name = tk.Label(reg, text="Sign in", pady=60, font=('Arial', 18))
signin_name.pack()
use = tk.Label(reg, text="Enter username", font=('Arial', 12))
use.pack()
username_s = tk.StringVar()
username_sE = tk.Entry(reg, textvariable=username_s, width=40)
username_sE.pack()
pse = tk.Label(reg, text="Enter password", font=('Arial', 12))
pse.pack()
password_s = tk.StringVar()
password_sE = tk.Entry(reg, textvariable=password_s, width=40)
password_sE.pack()
ready_reg = tk.Button(reg, text="sign in", background="#fff",
padx="20", pady="8", font=('Arial', 16), command=SignAccount)
ready_reg.place(relx=.5, rely=.8, anchor="c", height=30, width=190)
reg.mainloop()
def SignOut():
pass
screen = tk.Tk()
screen.title("SnakeBoom - Arthur Topal, arthurtopal342#gmail.com")
screen.geometry("460x600")
screen.resizable(width=False, height=False)
name = tk.Label(screen, text="SnakeBoomツ", font=("Arial", 24), pady=30)
name.pack()
start_btn = tk.Button(screen, text="Start", background="#fff", padx="20", pady="8", font=('Arial', 16), command=Start)
start_btn.place(relx=.5, rely=.3, anchor="c", height=30, width=130)
quit_btn = tk.Button(screen, text="Quit", background="#fff", padx="20", pady="8", font=('Arial', 16), command=Quit)
quit_btn.place(relx=.5, rely=.4, anchor="c", height=30, width=130)
reg_btn = tk.Button(screen, text="Registration", background="#fff", padx="20", pady="8", font=('Arial', 16), command=Reg)
reg_btn.place(relx=.5, rely=.8, anchor="c", height=30, width=230)
signin_btn = tk.Button(screen, text="Sign In", background="#fff", padx="20", pady="8", font=('Arial', 16), command=SignIn)
signin_btn.place(relx=.5, rely=.86, anchor="c", height=30, width=230)
signout_btn = tk.Button(screen, text="Sign Out", background="#fff", padx="20", pady="8", font=('Arial', 16), command=SignOut)
signout_btn.place(relx=.5, rely=.92, anchor="c", height=30, width=230)
# speak("Welcome to the Snake Boom, to start game please sign in or registrant, and press button Start. To quit press button quit")
screen.mainloop()
Couple things to help... I'm no tk expert, but your data is a little wonky.
print out the data that you intend to write to the file. I'm getting all empty strings, this is a tk thing...not sure why
You are writing a dictionary with one user in it. I think you want either a list of dictionaries or a dictionary of dictionaries keyed by user name. If you want to do a list, because you are checking them with iteration, you can try:
--
db = []
entry = {
"username": username_reg.get(),
"mail": mail_reg.get(),
"password": password_reg.get(),
"best_score": 0
}
db.append(entry)
print(f'about to write: {db}') # for error checking
file = open("db/users.pkl", "wb")
pickle.dump(db, file)
file.close()
When you are reading it back in, you only get to read it once. You are attempting to read it twice without closing the file. Try this:
--
file = open("db/users.pkl", "rb")
data = pickle.load(file)
file.close()
print(f'Received from file: {data}')
for i in data: # do not re-read the data here, it will be empty!
....
Note: You need to think about the data container for your users. I would suggest a dictionary of dictionaries. Outer key would be username, then each sub-dictionary would contain that user data

How to take information thats entered into a entry box and save it in a text file

So basically when i enter information into the two entry boxes, i want the data to go into a text file which can be accessed on other pages, but at the moment i need help to define the function i'm coding. If you do help, note that a new page (notepad preferably) needs to be added called "student". from #function onwards the code is abit messy and the code on the next line after def adduser(): is incorrect.
from tkinter import*
window = Tk()
window.title("Spelling Bee Opener")
window.geometry("600x400+500+250")
window.configure(bg="yellow")
label = Label(window,text = "Please Enter Your new Username and Password in the boxes below")
label.configure(bg='yellow')
label.place(x= 50, y=25)
Student=[]
#Username Entry
label = Label(window, text="Username")
label.configure(bg='Yellow')
label.place(x=50, y=70)
entry_box1=Entry(window,)
entry_box1.place(x=110,y=70)
#Password Entry
label = Label(window, text="Password")
label.configure(bg='Yellow')
label.place(x=50, y=100)
entry_box2=Entry(window,)
entry_box2.place(x=110, y=100)
# Function
def adduser():
addstudent = open ("student.txt", "w")
addstudent.write()
window.destroy()
b = Button(window, borderwidth=2, text="Add New user", width=12, pady=5, command=adduser)
b.place(x=110,y=125)
window.mainloop()
You can use .get() to get that text in entry.
def adduser():
addstudent = open ("student.txt", "w")
addstudent.write("User ID: " + entry_box1.get())
addstudent.write("\nUser Password: " + entry_box2.get())
addstudent.close ()
window.destroy()

Categories