Why my pickle database that is in my game doesnt work - python

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

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

How can i get the value from the entry and inject into the init function parameter?

Here's the code:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
import time
import sys
class TwitterBot:
def __init__(self, username, password):
self.username = username
self.password = password
entry_user = tk.Entry(lower_frame, bg="white", fg='black', bd=0)
#entry_user.insert(0, "Username")
#entry_user.bind("<Button-1>", del_value_user)
entry_user.pack(expand = "yes")
entry_pass = tk.Entry(lower_frame, bg="white", fg='black', bd=0)
#entry_pass.insert(0, "Password")
#entry_pass.bind("<Button-1>", del_value_pass)
entry_pass.pack(expand = "yes")
sasha = TwitterBot(entry_user.get(), entry_pass.get())
The entry never send the values I typed in into sasha = TwitterBot(entry, entry2)
Meaning I want that inside tkinter interface, I type in two entries that supposed to be username and password and when I execute the function those values get injected. I think the problem is that self.username and self.password are defined inside of the __init__ and so if those entries stay empty at the launch so i cant get them to inject. cause I can print my entry.get() values. I just cant make them replace the two first parameters of my __init__ function. Does anybody knows how to help?
Try this:
import tkinter as tk
class TwitterBot:
def __init__(self, username, password):
print("Username =", username, " Password =", password)
self.username = username
self.password = password
def create_bot(event=None):
sasha = TwitterBot(entry_user.get(), entry_pass.get())
print("started bot")
root = tk.Tk()
entry_user = tk.Entry(root, bg="white", fg='black', bd=0)
#entry_user.insert(0, "Username")
#entry_user.bind("<Button-1>", del_value_user)
entry_user.pack(expand=True)
# Log in if the user presses the Enter key:
entry_user.bind("<Return>", create_bot)
entry_pass = tk.Entry(root, bg="white", fg='black', bd=0)
#entry_pass.insert(0, "Password")
#entry_pass.bind("<Button-1>", del_value_pass)
entry_pass.pack(expand=True)
# Log in if the user presses the Enter key:
entry_pass.bind("<Return>", create_bot)
button = tk.Button(root, text="Log in", command=create_bot)
button.pack()
root.mainloop()
Your code wasn't working because as soon as your code created the entries it tried to get the data out of them (which obviously is an empty string) and created the TwitterBot object. To make it work you have to give the user time to enter their details in the entries by adding a button/binding to the user pressing the Enter key.
I created a button and placed it at the bottom of the window. When you click the button it calls create_bot which creates the TwitterBot object.
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
import time
import sys
import tkinter as tk
from tkinter import *
from tkmacosx import Button as button
class TwitterBot:
def __init__(self, username, password):
print("Username =", username, " Password =", password)
self.username = username
self.password = password
def open_br(self):
self.bot = webdriver.Firefox()
def end_br(self):
self.bot.quit()
def login(self):
bot = self.bot
bot.get("http://twitter.com/login/")
time.sleep(3)
email = bot.find_element_by_name("session[username_or_email]")
password = bot.find_element_by_name("session[password]")
email.clear()
password.clear()
email.send_keys(self.username)
password.send_keys(self.password)
password.send_keys(Keys.RETURN)
time.sleep(3)
def like_tweet(self, hashtag):
bot = self.bot
bot.get('https://twitter.com/search?q='+hashtag+'&src=typed_query')
time.sleep(3)
for i in range(1,8):
bot.execute_script('window.scrollTo(0,document.body.scrollHeight)')
time.sleep(2)
tweets = bot.find_elements_by_class_name('tweet')
tweetLinks = [i.get_attribute('href') for i in bot.find_elements_by_xpath("//a[#dir='auto']")]
filteredTweet = list(filter(lambda x: 'status' in x,tweetLinks))
print(filteredTweet)
for link in filteredTweet:
bot.get(link)
time.sleep(5)
if drop2_var.get() == "Retweet":
try:
bot.find_element_by_xpath("//div[#data-testid='retweet']").click()
bot.find_element_by_xpath("//div[#data-testid='retweetConfirm']").click()
time.sleep(3)
except Exception as ex:
time.sleep(10)
elif drop2_var.get() == "Likes":
bot.find_element_by_xpath("//div[#data-testid='like']").click()
time.sleep(3)
# def create_bot(event=None):
# sasha = TwitterBot(entry_user.get(), entry_pass.get())
# print("started bot")
sasha = TwitterBot("", "")
root = tk.Tk()
HEIGHT = 800
WIDTH = 400
#FUNCTIONS CLEARING ENTRY
def del_value(event): # note that you must include the event as an arg, even if you don't use it.
entry.delete(0, "end")
return None
def del_value_user(event): # note that you must include the event as an arg, even if you don't use it.
entry_user.delete(0, "end")
return None
def del_value_pass(event): # note that you must include the event as an arg, even if you don't use it.
entry_pass.delete(0, "end")
return None
def ex():
root.quit()
#PROGRAM SETTINGS
root.title("Social Bot")
root.minsize(400, 800)
#root.iconbitmap("/Users/sashakharoubi/Desktop/BOOTCAMP/Week 9/Day 2/image/logo.ico")
root.config(background="#66b3ff")
canvas = tk.Canvas(root, height= HEIGHT, width = WIDTH, bd=0, highlightthickness = 0)
canvas.pack()
# background_image = tk.PhotoImage(file = 'blue.png')
# background_label = tk.Label(root, image =background_image)
# background_label.place(x=0, y=0, relwidth=1, relheight=1)
#MAINFRAME
frame = tk.Frame(root, bg="#222f3e")
frame.place(relx = 0, rely = 0, relwidth = 1, relheight = 1)
#SUBPART FRAME
lower_frame = tk.Frame(root, bg="#E9E9E9", bd=0, highlightthickness = 0, relief="sunken")
#DROPDOWN MENU OPTIONS
OPTIONS = [
"Twitter",
"Instagram(not working)"
]
OPTIONS2 = [
"Likes",
"Retweet"
]
entry_txt = tk.Label(lower_frame, text="Welcome to Social Bot\n\nChoose an action to execute", font=("Montserrat", 15), bg="#E9E9E9", fg="black")
entry_txt.pack(expand = "yes")
#DROPDOWN MENU
drop_var = StringVar(lower_frame)
drop_var.set(OPTIONS[0])
drop2_var = StringVar(lower_frame)
drop2_var.set(OPTIONS2[0])
drop = OptionMenu(lower_frame, drop_var, *OPTIONS)
drop.config(fg="black")
drop.pack()
drop2 = OptionMenu(lower_frame, drop2_var, *OPTIONS2)
drop2.config(fg="black")
drop2.pack()
#ENTRIES
entry = tk.Entry(lower_frame, bg="white", fg='black', bd=0)
entry.insert(0, "-->Topic to like or retweet")
entry.bind("<Button-1>", del_value)
entry.pack(expand = "yes")
entry_user = tk.Entry(lower_frame, bg="white", fg='black', bd=0)
entry_user.insert(0, "----Type Your Username---")
entry_user.bind("<Button-1>", del_value_user)
entry_user.pack(expand = "yes")
#entry_user.bind("<Return>", create_bot)
entry_pass = tk.Entry(lower_frame, bg="white", fg='black', bd=0)
entry_pass.insert(0, "----Type Your Password---")
entry_pass.bind("<Button-1>", del_value_pass)
entry_pass.pack(expand = "yes")
#entry_pass.bind("<Return>", create_bot)
#BUTTONS
button_confirm = button(lower_frame, text="Confirm", bg="white", fg="black")
button_confirm.pack(pady=25, side = 'top')
button_open = button(lower_frame, text="Open Browser", bg="white", fg="black", command= sasha.open_br)
button_open.pack(pady=25, side = 'top')
button_log = button(lower_frame, text="LOG IN", bg='#54a0ff', fg="white", command =sasha.login, bd=0, highlightthickness = 0)
button_log.pack(pady=25, side = 'left')
button_launch = button(lower_frame, text="START", bg='#1dd1a1', fg="white", relief="flat", command = lambda: sasha.like_tweet(entry.get()), bd=0, highlightthickness = 0)
button_launch.pack(pady=25, side = 'right')
button_stop = button(lower_frame, text="STOP", bg="#ff6b6b", fg="white", command= sasha.end_br)
button_stop.pack(pady=25, side = 'bottom')
button_exit = button(lower_frame, text="Exit", bg ="white", fg="black", command= ex)
button_exit.pack(side = 'bottom')
lower_frame.place(relx = 0.1, rely = 0.1, relwidth=0.8, relheight=0.8)
#TITLE
label = tk.Label(frame, text="S O C I A L B O T", font=("Montserrat", 25), bg="white", fg="#222f3e")
label.pack(side="top", fill ="both")
root.mainloop()
v1 = browser.find_element_by_xpath("").text
try put .text at last of your code
then you can print or use v1 as a value

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.

How can I run this code without using global variables?

(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.

An unexpected window appears in tkinter python

I made a separate file called clinic1.py for the other code and import it to the main page. Everything works fine however another window appears when I click save button on the add new item page.
When I place all the code on the main page that small window doesn't appear.
I cant find whats causing another window to appear when it's in a separate file.
This is my main page:
from tkinter import *
from tkinter import ttk
import tkinter.messagebox
large_font = ('Verdana',12)
storedusername =['foo'] storedpass=['123'] storedretype=[]
list_of_users=storedusername
list_of_passwords=storedpass
def all_clinic_frames(event):
combo_clinic=combo.get()
if combo_clinic == 'Clinic 1':
enter()
root = Tk()
root.geometry('800x600')
root.title('CSSD')
topFrame=Frame(root,width=800,height=100,padx=310)
area=Label(topFrame,text='CSSD')
area.config(font=("Courier", 50))
frame=Frame(root,highlightbackground="black", highlightcolor="black", highlightthickness=1, width=100, height=100, bd= 0)
frame.place(relx=.5, rely=.5, anchor="center")
username = Label(frame, text='User Name') username.config(font='Arial',width=15) password = Label(frame, text='Password') password.config(font='Arial',width=15) enteruser = Entry(frame, textvariable=StringVar(),font=large_font) enterpass = Entry(frame, show='*', textvariable=StringVar(),font=large_font)
combo_choice=StringVar()
combo=ttk.Combobox(frame,textvariable=combo_choice)
combo['values']=('Clinic 1')
combo.state(['readonly'])
combo.grid(row=0,sticky=NW)
combo.set('Choose Area...')
combo.bind('<<ComboboxSelected>>',all_clinic_frames)
topFrame.grid(row=0,sticky=N) topFrame.grid_propagate(False) area.grid(row=0,column=1,sticky=N) username.grid(row=1, sticky=E) enteruser.grid(row=1, column=1) password.grid(row=2, sticky=E) enterpass.grid(row=2, column=1)
def valid():
usernameRight=enteruser.get()
passwordRight=enterpass.get()
while True:
try:
if (usernameRight==list_of_users[0]) and (passwordRight==list_of_passwords[0]):
import clinic1
clinic1.main_page()
quit()
break
except IndexError:
invalid = Label(frame, text='User name or Password is incorrect!', fg='red')
invalid.grid(row=3, columnspan=2)
break
def enter():
register = Button(frame, text='Sign In',relief=RAISED,fg='white',bg='red',command=valid)
register.grid(row=3,column=1,ipadx=15,sticky=E)
def quit():
root.destroy()
And this is the second file that I imported in the main page which i saved as clinic1.py
from tkinter import*
import tkinter.messagebox
newInstList=[]
def addItem(event=None):
global back_add,quantityentry,itemEntry,itemEntry1,quantityentry1
itemFrameTop=Frame(root, width=800,height=100,bg='pink')
itemFrameTop.grid_propagate(False)
itemFrameTop.grid(row=0)
area1_item = Label(itemFrameTop, text='CSSD', pady=5,padx=230)
area1_item.config(font=("Courier", 30))
area1_item.grid_propagate(False)
area1_item.grid(row=0,column=1,sticky=NE)
clinic_1 = Label(itemFrameTop, text='Clinic 1', bg='red', fg='white', bd=5)
clinic_1.config(font=("Courier", 15))
clinic_1.grid_propagate(False)
clinic_1.grid(row=1, sticky=W,padx=10)
itemFrameMid=Frame(root,width=700,height=600,bg='blue')
itemFrameMid.grid_propagate(False)
itemFrameMid.grid(row=1)
itemname=Label(itemFrameMid,text='Item name:')
itemname.config(font=('Arial,15'))
itemname.grid_propagate(False)
itemname.grid(row=1,sticky=E)
quantity=Label(itemFrameMid,text='Qty:')
quantity.config(font=('Arial,15'))
quantity.grid_propagate(False)
quantity.grid(row=1,column=3, sticky=E,padx=10)
itemEntry=Entry(itemFrameMid)
itemEntry.config(font=('Arial,15'))
itemEntry.grid(row=1,column=1,sticky=EW,padx=30,pady=10)
itemEntry1 = Entry(itemFrameMid)
itemEntry1.config(font=('Arial,15'))
itemEntry1.grid(row=2, column=1)
quantityentry=Entry(itemFrameMid,width=5)
quantityentry.config(font=('Arial',15))
quantityentry.grid(row=1, column=4)
quantityentry1 = Entry(itemFrameMid, width=5)
quantityentry1.config(font=('Arial', 15))
quantityentry1.grid(row=2, column=4,padx=10)
"""When I click save button another small window appears"""
okbutton = Button(itemFrameMid, text='Save', command=saveCheck)
okbutton.config(font=('Arial', 12))
okbutton.grid(row=3, column=4, padx=15)
back_add = Label(itemFrameTop, text='Back')
back_add.config(font=('Courier,15'))
back_add.grid(row=0, sticky=W, padx=30)
back_add.bind('<Button-1>', main_page)
back_add.bind('<Enter>', red_text_back1)
back_add.bind('<Leave>', black_text_back1)
def saveCheck():
saveQuestion=tkinter.messagebox.askquestion('CSSD', 'Are you sure you want to save?')
if saveQuestion == 'yes':
newInstList.append(itemEntry.get())
newInstList.append(quantityentry.get())
newInstList.append(itemEntry1.get())
newInstList.append(quantityentry1.get())
print(newInstList)
main_page()
elif saveQuestion == 'no':
pass
def red_text_back1(event=None):
back_add.config(fg='red')
def black_text_back1(event=None):
back_add.config(fg='black')
def red_text_add(event=None):
addnew.config(fg='red')
def black_text_add(event=None):
addnew.config(fg='black')
def main_page(event=None):
global addnew,usedInst,logOut
frame1 = Frame(root, width=800, height=100,bg='pink')
frame1.grid(row=0, column=0, sticky="nsew")
frame1.grid_propagate(False)
midframe1=Frame(root,width=800,height=600)
midframe1.grid_propagate(False)
midframe1.grid(row=1)
area1 = Label(frame1, text='CSSD',pady=5,padx=350)
area1.config(font=("Courier", 30))
area1.grid(row=0)
clinic1=Label(frame1,text='Clinic 1',bg='red',fg='white',bd=5)
clinic1.config(font=("Courier", 15))
clinic1.grid_propagate(False)
clinic1.grid(row=1,sticky=W,padx=10)
addnew=Label(midframe1,text='+ Add new item')
addnew.config(font=('Arial',15))
addnew.grid(row=2,column=1,sticky=E,ipadx=50)
addnew.bind('<Button-1>', addItem)
addnew.bind('<Enter>', red_text_add)
addnew.bind('<Leave>', black_text_add)
root = Tk()
root.geometry('800x600')
Both files have this line of code:
root = Tk()
Each time you do that, you get another root window. A tkinter application needs to have exactly one instance of Tk running at a time.
You need to remove the last two lines from clinic1.py. You will also need to pass in the reference to root to any methods from clinic1.py that need it.
First file.
from tkinter import *
from tkinter import ttk
import tkinter.messagebox
large_font = ('Verdana',12)
storedusername =['foo']
storedpass=['123']
storedretype=[]
list_of_users=storedusername
list_of_passwords=storedpass
def all_clinic_frames(event):
combo_clinic=combo.get()
if combo_clinic == 'Clinic 1':
enter()
root = Tk()
root.geometry('800x600')
root.title('CSSD')
topFrame=Frame(root,width=800,height=100,padx=310)
area=Label(topFrame,text='CSSD')
area.config(font=("Courier", 50))
frame=Frame(root,highlightbackground="black", highlightcolor="black", highlightthickness=1, width=100, height=100, bd= 0)
frame.place(relx=.5, rely=.5, anchor="center")
myvar=StringVar()
username = Label(frame, text='User Name')
username.config(font='Arial',width=15)
password = Label(frame, text='Password')
password.config(font='Arial',width=15)
enteruser = Entry(frame, textvariable=myvar, font=large_font)
pass1=StringVar()
enterpass = Entry(frame, show='*', textvariable=pass1, font=large_font)
combo_choice=StringVar()
combo=ttk.Combobox(frame,textvariable=combo_choice)
combo['values']=[('Clinic 1')]
combo.state(['readonly'])
combo.grid(row=0,sticky=NW)
combo.set('Choose Area...')
combo.bind('<<ComboboxSelected>>',all_clinic_frames)
topFrame.grid(row=0,sticky=N)
topFrame.grid_propagate(False)
area.grid(row=0,column=1,sticky=N)
username.grid(row=1, sticky=E)
enteruser.grid(row=1, column=1)
password.grid(row=2, sticky=E)
enterpass.grid(row=2, column=1)
def valid():
usernameRight=enteruser.get()
passwordRight=enterpass.get()
while True:
try:
if (usernameRight==list_of_users[0]) and (passwordRight==list_of_passwords[0]):
import clinic1
clinic1.main_page(root)
# quit()
break
except IndexError:
invalid = Label(frame, text='User name or Password is incorrect!', fg='red')
invalid.grid(row=3, columnspan=2)
break
def enter():
register = Button(frame, text='Sign In',relief=RAISED,fg='white',bg='red',command=valid)
register.grid(row=3,column=1,ipadx=15,sticky=E)
def quit():
root.destroy()
root.mainloop()
clinic1.py
from tkinter import*
import tkinter.messagebox
newInstList=[]
def addItem(root, event=None):
global back_add,quantityentry,itemEntry,itemEntry1,quantityentry1
if event is None:
event = Event()
itemFrameTop=Frame(root, width=800, height=100, bg='pink')
itemFrameTop.grid_propagate(False)
itemFrameTop.grid(row=0)
area1_item = Label(itemFrameTop, text='CSSD', pady=5,padx=230)
area1_item.config(font=("Courier", 30))
area1_item.grid_propagate(False)
area1_item.grid(row=0,column=1,sticky=NE)
clinic_1 = Label(itemFrameTop, text='Clinic 1', bg='red', fg='white', bd=5)
clinic_1.config(font=("Courier", 15))
clinic_1.grid_propagate(False)
clinic_1.grid(row=1, sticky=W,padx=10)
itemFrameMid=Frame(root,width=700,height=600,bg='blue')
itemFrameMid.grid_propagate(False)
itemFrameMid.grid(row=1)
itemname=Label(itemFrameMid,text='Item name:')
itemname.config(font=('Arial,15'))
itemname.grid_propagate(False)
itemname.grid(row=1,sticky=E)
quantity=Label(itemFrameMid,text='Qty:')
quantity.config(font=('Arial,15'))
quantity.grid_propagate(False)
quantity.grid(row=1,column=3, sticky=E,padx=10)
itemEntry=Entry(itemFrameMid)
itemEntry.config(font=('Arial,15'))
itemEntry.grid(row=1,column=1,sticky=EW,padx=30,pady=10)
itemEntry1 = Entry(itemFrameMid)
itemEntry1.config(font=('Arial,15'))
itemEntry1.grid(row=2, column=1)
quantityentry=Entry(itemFrameMid,width=5)
quantityentry.config(font=('Arial',15))
quantityentry.grid(row=1, column=4)
quantityentry1 = Entry(itemFrameMid, width=5)
quantityentry1.config(font=('Arial', 15))
quantityentry1.grid(row=2, column=4,padx=10)
"""When I click save button another small window appears"""
okbutton = Button(itemFrameMid, text='Save', command=lambda: saveCheck(root))
okbutton.config(font=('Arial', 12))
okbutton.grid(row=3, column=4, padx=15)
back_add = Label(itemFrameTop, text='Back')
back_add.config(font=('Courier,15'))
back_add.grid(row=0, sticky=W, padx=30)
back_add.bind('<Button-1>', main_page)
back_add.bind('<Enter>', red_text_back1)
back_add.bind('<Leave>', black_text_back1)
def saveCheck(root):
saveQuestion=tkinter.messagebox.askquestion('CSSD', 'Are you sure you want to save?')
if saveQuestion == 'yes':
newInstList.append(itemEntry.get())
newInstList.append(quantityentry.get())
newInstList.append(itemEntry1.get())
newInstList.append(quantityentry1.get())
print(newInstList)
main_page(root)
elif saveQuestion == 'no':
pass
def red_text_back1(event=None):
back_add.config(fg='red')
def black_text_back1(event=None):
back_add.config(fg='black')
def red_text_add(event=None):
addnew.config(fg='red')
def black_text_add(event=None):
addnew.config(fg='black')
def main_page(root):
global addnew,usedInst,logOut
frame1 = Frame(root, width=800, height=100,bg='pink')
frame1.grid(row=0, column=0, sticky="nsew")
frame1.grid_propagate(False)
midframe1=Frame(root,width=800,height=600)
midframe1.grid_propagate(False)
midframe1.grid(row=1)
area1 = Label(frame1, text='CSSD',pady=5,padx=350)
area1.config(font=("Courier", 30))
area1.grid(row=0)
clinic1=Label(frame1,text='Clinic 1',bg='red',fg='white',bd=5)
clinic1.config(font=("Courier", 15))
clinic1.grid_propagate(False)
clinic1.grid(row=1,sticky=W,padx=10)
addnew=Button(midframe1,text='+ Add new item', font=('Arial', 15), command=lambda: addItem(root))
addnew.grid(row=2,column=1,sticky=E,ipadx=50)
# addnew.bind('<Button-1>', lambda r=root: addItem(r))
addnew.bind('<Enter>', red_text_add)
addnew.bind('<Leave>', black_text_add)

Categories