Python GUI popup - python

import random
import string
import PySimpleGUI as sg
filename = r'C:\Users\teeki\Documents\Passwords\passwords.txt'
def new_password():
print("For which account you want your password: ")
account = input();
length = int(input('\nHow long do you want your password to be: '))
lower = string.ascii_lowercase
upper = string.ascii_uppercase
num = string.digits
symbols = string.punctuation
#All possible symbols to be used in password
all_symbols = lower + upper + num + symbols
#we generate <length> long password and print it out
temp = random.sample(all_symbols,length)
password = "".join(temp)
# We save password to the passwords.txt
text_file = open(r'C:\Users\teeki\Documents\Passwords\passwords.txt' , 'a')
n = text_file.write('\n' + account + ' password: ' + password)
text_file.close()
print("Your password is: ", password)
def popup_text(filename, text):
layout = [
[sg.Multiline(text, size=(80, 25)),],
]
win = sg.Window(filename, layout, modal=True, finalize=True)
while True:
event, values = win.read()
if event == sg.WINDOW_CLOSED:
break
win.close()
sg.theme('LightBlue3')
layout = [[sg.Text("Welcome to Password Generator")], [sg.Button("Exit")], [sg.Button("Password List"), sg.Button("New Password")]]
window = sg.Window("Password Generator", layout)
while True:
event, values = window.read()
if event == "Exit" or event == sg.WIN_CLOSED:
break
elif event == "Password List":
with open(filename, "rt", encoding='utf-8') as f:
text = f.read()
popup_text(filename, text)
elif event == "New Password":
new_password()
window.close()
I need help with making a popup. So far the code works just fine, but instead of when i press on New Password printing on terminal i want it to open new popup where i would have 2 input fields and button to save password into .txt file.
I've tried messing around with sg.Popup but i cant get it to work properly. So any advice would be appreciated.

Example for you,
import random
import string
import PySimpleGUI as sg
def generate_password(account, length):
return 'new password'
filename = r'C:\Users\teeki\Documents\Passwords\passwords.txt'
def new_password():
layout = [
[sg.Text("Password Account"), sg.Input(key='account')],
[sg.Text("Password Length "), sg.Input(key='length' )],
[sg.Button("Generate"), sg.Text("", size=(0, 1), key='password')],
]
window = sg.Window('New Password', layout, modal=True)
while True:
event, values = window.read()
if event == sg.WIN_CLOSED:
break
elif event == "Generate":
account = values['account']
length = int(values['length'])
password = generate_password(account, length)
if password:
window['password'].update(value=password)
else:
window['password'].update(value='')
window.close()
def popup_text(filename, text):
sg.Window(filename, [[sg.Multiline(text, size=(80, 25))]], modal=True
).read(close=True)
sg.theme("DarkBlue3")
sg.set_options(font=("Courier New", 16))
layout = [
[sg.Text("Welcome to Password Generator")],
[sg.Button("Exit")],
[sg.Button("Password List"), sg.Button("New Password")]]
window = sg.Window("Password Generator", layout)
while True:
event, values = window.read()
if event == "Exit" or event == sg.WIN_CLOSED:
break
elif event == "Password List":
with open(filename, "rt", encoding='utf-8') as f:
text = f.read()
popup_text(filename, text)
elif event == "New Password":
new_password()
window.close()

Related

Saving user Input from Input Command simplepyGUI

I am having trouble save the user's name into a list once order is pressed. I also need to store the user's selction with the buttons into the same list--i believe i need a dis tionary for this but I am completely lost.
For example:
John presses Burger, Onions, Bacon, and Eggs. he hits submit.
I need the out put to relay "John's Order: Burger, Onions, Bacon, Eggs. Total: $XX.XX"
is this possible? And maybe if someone knows how to save the output into a onedrive file
here is my code:
import PySimpleGUI as sg
menu_dictionary = {
"Cheese":0.50,
"Sandwhich":1.75,
"Pickles":0.25,
"Hot Dog":1.25,
"Burger": 3.5,
"Onions": 0.75,
"Bacon": 1.25,
"Eggs": 1.00,
"Gatorade": 1.25
}
total=0
name= []
sg.theme('Dark Amber')
layout = [
[sg.Text("Welcome to the MAF Menu")],
[sg.Text("Enter your name:"), sg.Input(), sg.Button("Order")],
[sg.Text("Entrees"), sg.Button("Burger"), sg.Button("Sandwhich"), sg.Button("Hot Dog"), sg.Button("Eggs")],
[sg.Text("Sides"),sg.Button("Onions"), sg.Button("Pickles"), sg.Button("Cheese")],
[sg.Text("Total $" + str(total), key='Total'), sg.Text(name, key='Order')],
[sg.Button("Exit"), sg.Button("Clear")],]
window = sg.Window('MAF Menu', layout)
while True:
event, values = window.read()
if event == "Order":
name.append()
window['Order'].update("Order")
if event in menu_dictionary:
total = total + menu_dictionary[event]
window['Total'].update("Total $" + str(total))
if event == "Clear":
total=0
window['Total'].update("Total $0")
if event == sg.WIN_CLOSED or event == 'Exit':
sg.popup_no_titlebar('Are you sure?')
break
window.close()
I keep getting errors that the list is not populating
You just simply not need to append the name as your name is single value comming from textbox, and use a list to keep track of all items ordered
import PySimpleGUI as sg
menu_dictionary = {
"Cheese":0.50,
"Sandwhich":1.75,
"Pickles":0.25,
"Hot Dog":1.25,
"Burger": 3.5,
"Onions": 0.75,
"Bacon": 1.25,
"Eggs": 1.00,
"Gatorade": 1.25
}
total=0
items = []
name = ''
sg.theme('Dark Amber')
layout = [
[sg.Text("Welcome to the MAF Menu")],
[sg.Text("Enter your name:"), sg.Input(), sg.Button("Order")],
[sg.Text("Entrees"), sg.Button("Burger"), sg.Button("Sandwhich"), sg.Button("Hot Dog"), sg.Button("Eggs")],
[sg.Text("Sides"),sg.Button("Onions"), sg.Button("Pickles"), sg.Button("Cheese")],
[sg.Text("Total $" + str(total), key='Total'), sg.Text(name, key='Order')],
[sg.Button("Exit"), sg.Button("Clear")],]
window = sg.Window('MAF Menu', layout)
while True:
event, values = window.read()
if event == "Order":
print(values[0])
order = ", ".join(items)
order = "{}'s Order: {}".format(name, order)
print(order)
if event in menu_dictionary:
total = total + menu_dictionary[event]
if event not in items:
items.append(event)
window['Total'].update("Total $" + str(total))
if event == "Clear":
total=0
items = []
window['Total'].update("Total $0")
if event == sg.WIN_CLOSED or event == 'Exit':
sg.popup_no_titlebar('Are you sure?')
break
window.close()

Get event to run when Input in empty

I want an event to run when I type in the input, that works.
But only when I type something, not when the field is empty, I want that too
Here's a little template code I wrote that resembles my issue
import PySimpleGUI as sg
list1 = ['a', 'b', 'c']
matches = []
out = []
layout = [
[sg.InputText('', key='-search-', change_submits=True)],
[sg.Listbox(values=out, key='-list-', size=(10,10))]
]
window = sg.Window('Search', layout, size=(300, 300))
while True:
event, values = window.read()
if values['-search-']:
SearchTerm = values['-search-']
SearchTerm.replace("['", "")
SearchTerm.replace("']", "")
print("Search Term = " + SearchTerm)
if SearchTerm == "":
out = list1
window.Element('-list-').Update(values=list1)
if SearchTerm != "":
for i in list1:
if SearchTerm in i:
if i not in matches:
matches.append(i)
outlist = matches
window.Element('-list-').Update(values=outlist)
if event == sg.WIN_CLOSED or event == 'Exit':
break
There's re lot of events in event loop, so you have to decide how to check what the event is. For example, if values['-search-']: will be failed it you close the window and values maybe None, then you will get exception TypeError: 'NoneType' object is not subscriptable.
In your event loop, you didn't check the case values['-search-']=='', but just check SearchTerm == "" under the event values['-search-']!=''.
The pattern for event loop maybe like this
while True:
event, values = window.read()
if event in (sg.WIN_CLOSED, 'Exit'):
break
if event == '-search-':
if values[event]:
""" Code if Input element not empty """
else:
""" Code if Input element is empty """
window.close()

pulling information from nested dictionaries: TypeError: list indices must be integers or slices, not str

I put some information into a file which is read out and put into a nested dictionary and Signup works fine until you want to login as it says:
second = account[user]["second"]
TypeError: list indices must be integers or slices, not str
This happens when I want to call back the time from the users dictionary but everything else works.
Sorry for a mess but I'm too puzzled to why it is doing this.
Please help
Sorry for any inconvenience
import os
from itertools import islice
import sys
import time
import random as r
from tkinter import *
from functools import partial
from tkinter import messagebox as error
import re
import tkinter as tk
s=0
account= []
accounts = {}
a=0
alphabet = "1234567890#.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!$%^&*()_+-=/*:;~#?>,<|\{}[]"""
letter_to_index = dict(zip(alphabet, range(len(alphabet))))
index_to_letter = dict(zip(range(len(alphabet)), alphabet))
regex = '^[a-z0-9]+[\._]?[a-z0-9]+[#]\w+[.]\w{2,3}$'
##Creates a new file for the database if it isnt found and goes to loginpopup
def filecreator():
f=open('accounts_project.txt', "w")
f.close()
loginpopup()
##Error is found here. this is meant to get the time (when account was created)from the nested
##dictionary and encrypt the password the same for comparing but it comes up: TypeError: list indices
##must be integers or slices, not str
def loginencrypt(user, passwd):
global accounts
hour = accounts[user]["hour"]
minute = accounts[user]["minute"]
second = account[user]["seconds"]
encrypted = ""
split_message = [
passwd[i : i + len(user)] for i in range(0, len(passwd), len(user))
]
for each_split in split_message:
i = 0
for letter in each_split:
number = (letter_to_index[letter] - hour + letter_to_index[user[i]] + minute - second - i) % len(alphabet)
encrypted += index_to_letter[number]
i += 1
return encrypted
##this sends data to loginencrypt to encrypt the password but also it compares data and will handle
emailing to account owners when it is implemented
def find_login(user, passwd):
global s
global accounts
userexist = accounts.get(user)
if userexist:
encrypt = loginencrypt(user, passwd)
if accounts[user]["password"] == encrypt:
print("Welcome to your account")
else:
error.showerror("Invalid Password","Wrong Password")
if s == 5:
error.showerror("Run","The real user of this account was contacted")
if accounts[user]["email"] == "no":
reset()
else:
print("no")
else:
s+=1
else:
error.showerror("Invalid account","Please Signup Instead")
##this encrypts the password to be stored inside of the database
def encrypt(passwd, user, hour, minute, second):
encrypted = ""
split_message = [
passwd[i : i + len(user)] for i in range(0, len(passwd), len(user))
]
for each_split in split_message:
i = 0
for letter in each_split:
number = (letter_to_index[letter] - hour + letter_to_index[user[i]] + minute - second - i) % len(alphabet)
encrypted += index_to_letter[number]
i += 1
return encrypted
##this opens the file and gets all the data from it (seperated by |)in the form of a nested
##dictionary.
def filereader():
global accounts
with open("accounts_project.txt", 'r') as f:
for line in f:
listDetails = line.strip().split('|')
usernames = listDetails[0]
accounts[usernames] = {"username": listDetails[0]}
accounts[usernames].update({"password": listDetails[1]})
accounts[usernames].update({"email": listDetails[2]})
accounts[usernames].update({"hour": listDetails[3]})
accounts[usernames].update({"minute": listDetails[4]})
accounts[usernames].update({"seconds": listDetails[5]})
loginpopup()
##this gets all the data made by signing up the account and seperates it with a | and saves it inside
##the file
def filesaver(account, login):
global accounts
save = ("|".join(account)+"\n")
f=open('accounts_project.txt', "a")
f.write(save)
f.close()
del account[0:6]
if login ==1:
print("hi")
else:
reset()
##this checks if a username is entered
def login(username, password):
user = username.get()
passwd = password.get()
if len(user)==0:
error.showerror("error","Please enter a username")
else:
find_login(user, passwd)
##this resets the login window as 5 tries were attempted to break in
def resetlogin():
global s
global tkWindow
s = 0
tkWindow.destroy()
filereader()
##this does the same but after signing up so only the login window is visible
def reset():
global tkWindow
global signupas
signupas.destroy()
tkWindow.destroy()
filereader()
##not implemented yet but it is meant to send the email to the user for verification
def checkuser_email(account, emails):
global signupas
global accountS
print(emails)
##this checks if the user exists, username is entered and password for registration, checks if email
##is entered when 2step is on.
##It might be on about the bottom bit of it but it worked fine there but I cant call it now.
def popup(username,password,var1, email, var2):
global accounts
global account
checklist= var1.get()
user = username.get()
passwd = password.get()
emails = email.get()
login = var2.get()
if len(user) == 0:
error.showerror("Invalid username","Please enter a username")
elif len(user)>0:
if len(passwd) < 7:
error.showerror("error","Password isn't 7 characters long")
else:
userexists = accounts.get(user)
if userexists:
error.showerror("username exists","Username already exists\n please login instead")
else:
if checklist == 1:
if len(emails)==0:
error.showerror("error","Enter email")
elif len(emails)>0:
if not re.match(r"^[A-Za-z0-9\.\+_-]+#[A-Za-z0-9\._-]+\.[a-zA-Z]*$", emails):
error.showerror("Invalid email","Please enter a valid email")
else:
account.append(user)
account.append(passwd)
checkuser_email(account, emails)
else:
##put Yes here
if error.askyesno("Are you sure?", "Are you sure? \nIt will be harder to retrieve your account.\n You can always add it later", icon='error')==True:
##could be on about this here?
##anyone know a better way of doing the same?
account.append(user)
emaila = "no"
t= time.localtime()
account.append(emaila)
hour = time.strftime("%H")
hour = int(hour)
minute = time.strftime("%M")
minute = int(minute)
second = time.strftime("%S")
second = int(second)
encrypted_pass = encrypt(passwd, user, hour, minute, second)
account.insert(1, encrypted_pass)
hour= str(hour)
minute= str(minute)
second = str(second)
account.append(hour)
account.append(minute)
account.append(second)
filesaver(account, login)
##this is the signup pop up. Dont tick anything and for he popup press yes.
def signup():
global signupas
signupas = tk.Toplevel()
signupas.geometry('400x200')
signupas.title("Sign Up")
usernameLabel = Label(signupas, text="Username")
usernameLabel.grid(row=0, column=0)
username = StringVar()
usernameEntry = Entry(signupas, textvariable=username)
usernameEntry.grid(row=0, column=1)
passwordLabel = Label(signupas,text="Password")
passwordLabel.grid(row=1, column=0)
password = StringVar()
passwordEntry = Entry(signupas, textvariable=password, show='*')
passwordEntry.grid(row=1, column=1)
var1 = IntVar()
Checkbutton(signupas, text="2step verification", variable=var1).grid(row=2, column=0)
var2 = IntVar()
Checkbutton(signupas, text="Login after?", variable=var2).grid(row=2, column=1)
emailLabel = Label(signupas, text="Email")
emailLabel.grid(row=3, column=0)
email = StringVar()
emailEntry = Entry(signupas, textvariable=email)
emailEntry.grid(row=3, column=1)
SignUp = partial(popup, username, password, var1, email, var2)
signupButton = Button(signupas, text="SignUp", command=SignUp).grid(row=5, column=0)
noteLabel = Label(signupas, text="For 2step verification tick box,\n type your email and Signup").grid(row=6, column=1)
signupas.mainloop()
##this checks if file is empty: locks the login button so signup is only possible
def loginpopup():
global tkWindow
tkWindow = Tk()
global accounts
print(accounts)
tkWindow.geometry('400x150')
tkWindow.title("Database Program")
usernameLabel = Label(tkWindow, text="Username").grid(row=0, column=0)
username = StringVar()
usernameEntry = Entry(tkWindow, textvariable=username).grid(row=0, column=1)
passwordLabel = Label(tkWindow,text="Password").grid(row=1, column=0)
password = StringVar()
passwordEntry = Entry(tkWindow, textvariable=password, show='*').grid(row=1, column=1)
Login = partial(login, username, password)
SignUp = partial(signup)
loginButton = Button(tkWindow, text="Login", command=Login)
loginButton.grid(row=4, column=0)
signupButton = Button(tkWindow, text="SignUp", command=SignUp).grid(row=4, column=1)
if os.path.getsize('accounts_project.txt') ==0:
loginButton['state'] = DISABLED
else:
loginButton['state'] = NORMAL
pass
tkWindow.mainloop()
##this controls what to do and if the file exists
file = os.path.exists('accounts_project.txt')
if file == True:
filereader()
else:
filecreator()
Change second = account[user]["seconds"]
to second = accounts[user]["seconds"]

how to make a savable ui in python

I have a project that allows the user to make a quiz on their own using some buttons and input
well i even want the user to be able to save their quiz in a file so they can load it in
i don't want something BIG!! a txt file will do..
i am using PySimpleGui and not Tkinter or anything..
i really don't know what i have made till now yet?(sorry i am not great with GUI)
i have a :
Main window
Editor window
And a form window
main window links the editor
editor links the form window
thanks for help in advance
if you need my code too then here
import pysimplegui as sg
layout = [
[sg.Button("Make new Form")],
[sg.Button("Open Form")]
]
window = sg.Window("Python Forms", layout)
def Form_Make():
layout_for_make_form = [
[sg.Button("Add multiple choice question")],
[sg.Button("Save Form")]
# some more items here..
]
make_form_window = sg.Window("Make a Form..", layout_for_make_form)
while True:
events, values = make_form_window.read()
if events == "Add multiple choice question":
pass # this should add a new multi choice question(working on it!)
elif events == "Save Form":
# save a form.. i am stuck on this.. :|
while True:
event,values = windows.read()
if event == "Make new Form":
Form_M()
i really don't know what it is doing yet i will have to make a new file and start from scratch :|
this will work for you :
import PySimpleGUI as sg
import os.path
layout = [
[sg.Button("Make new Form")],
[sg.Button("Open Form")],
[sg.Button("Exit")],
]
windows = sg.Window("Python Forms", layout)
questions = []
def Form_Make():
layout_for_make_form = [
[sg.Button("Add multiple choice question", key='add')],
[sg.Text('file path',size=(10,1)),sg.FileBrowse(key='filepath')],
[sg.Button("Save Form",key='save',visible=False)]
# some more items here..
]
make_form_window = sg.Window("Make a Form..", layout_for_make_form)
while True:
count = False
events, values = make_form_window.read()
if events == "add":
layout_for_question = [
[sg.Text('Must Enter all the filed for save question in file.')],
[sg.Text('Enter Question : ',size=(10,1)),sg.Input(key='question')],
[sg.Text('option1',size=(10,1)),sg.Input(key='option1')],
[sg.Text('option2',size=(10,1)),sg.Input(key='option2')],
[sg.Text('option3',size=(10,1)),sg.Input(key='option3')],
[sg.Text('option4',size=(10,1)),sg.Input(key='option4')],
[sg.Button('add')]
]
make_question_window = sg.Window('question ', layout_for_question)
while True:
events, values = make_question_window.read()
if events == None:
break
elif events == 'add' :
if values['question'] != '' and values['option1'] != '' and values['option2'] != '' and values['option3'] != '' and values['option4'] != '':
questions.append([values['question'],values['option1'],values['option2'],values['option3'],values['option4']])
print('value addded ')
count = True
if count == True:
make_form_window['save'].update(visible=True)
elif events == "save":
print(values['filepath'])
file = values['filepath']
if file != None:
f=open(file,'w+')
for x in questions:
for y in x:
f.write(y + '\n')
f.close()
print('save a form.. i am stuck on this.. :')
elif events == None:
break
while True:
event,values = windows.read()
if event == "Make new Form":
Form_Make()
elif event == 'Exit' or event == None :
break

When making a list from a file, if the file contains more than one value it does not recognise any of the values

I made a program that is supposed to take a list of usernames and passwords from a file. It works perfectly if the files only have one username and password but as soon as I include more than one of them, it does not recognise them at all. Here is the code below.
import easygui as e
import os
upper = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"]
lower = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"]
numbers = ["1","2","3","4","5","6","7","8","9","0"]
loginsystem = True
while loginsystem == True:
users = []
file = open("users.secure","r")
reading = True
while reading == True:
tempuser = file.readline()
if tempuser == "":
reading = False
else:
users.append(tempuser)
file.close()
passwords = []
file = open("passwords.secure","r")
reading = True
while reading == True:
temppassword = file.readline()
if temppassword == "":
reading = False
else:
passwords.append(temppassword)
file.close()
loginmsg = "Enter your username and password"
logintitle = "Login"
loginfieldnames = ["Username","Password"]
loginfieldvalues = []
login = True
while login == True:
loginfieldvalues =
e.multpasswordbox(loginmsg,logintitle,loginfieldnames)
while 1:
if loginfieldvalues == None: break
loginerrmsg = ""
for i in range(len(loginfieldnames)):
if loginfieldvalues[i].strip() == "":
loginerrmsg = loginerrmsg + ('"%s" is a required field.\n\n' % loginfieldnames[i])
if loginerrmsg == "": break
loginfieldvalues = e.multpasswordbox(loginerrmsg, logintitle, loginfieldnames, loginfieldvalues)
inputuser = loginfieldvalues[0]
inputpassword = loginfieldvalues[1]
if inputuser not in users:
e.msgbox("Unknown username.",title="Login",ok_button="Try Again")
else:
placement = users.index(inputuser)
if inputpassword != passwords[placement]:
e.msgbox("Invalid password.",title="Login",ok_button="Try Again")
else: login = False
e.msgbox("Welcome, " + inputuser,title="Login System",ok_button="Continue")
basicoptions = ["Logout","Quit"]
running = True
while running == True:
choice = e.buttonbox("What would you like to do?",title="Login System",choices=basicoptions)
if choice == "Quit":
os._exit(0)
else:
running = False
The files just contain the word "admin" and when I add another value, I add it onto the next line using "\nadmin2" when writing to the file.
io.readline() will return the newline. That means if you have only one entry, you're likely getting admin, but with more lines, you're getting admin\n.
Instead you can do:
tempuser = file.readline().strip()
Unrelated to the question, but you can cleanup the code a lot. For example for reading files:
def read_file(path):
with open(path, 'r') as f:
return [line.strip() for line in f]
users = read_file('users.secure')
passwords = read_file('passwords.secure')

Categories

Resources