Saving the value of a checkbox if it's on Tkinter - python

I need help. While I'm saving the value of "box" it just writes ".!checkbutton" instead of the value I want. Why does this happen and how to fix it.
So I want it to write the onvalue in the txt instead of .!checkbutton if the box is ticked
how to fix this
Also if there is a way to make the checkbox bigger I would appreciate it :)
# -*- coding: utf8 -*-
from tkinter import *
from tkinter import messagebox
import os
root = Tk()
root.title('Feedback')
root.geometry("400x400")
organizerlist = [
"213",
"1231",
"123",
"123",
"123",
"123",
"123",
"."
]
eventsnames = [
"Rocket League"
]
def run():
# getting the name
filename = filename_ent.get()
if filename == '':
# to show an error that boxes are empty
messagebox.showerror(
'File exists', 'File already exists, try some other name thas is not used before')
if os.path.exists(f'{filename}.txt'):
# to show an error if the file already exists
messagebox.showerror(
'File exists', 'File already exists, try some other name not used before')
else:
# to open the file for python
new = open(f'{filename}.txt', '+w', encoding='utf-8')
# to write the name and email inside the file
new.write(f'''Admin of the event: {clicked.get()}\n{responsible.get()} \n{box}''')
lfilename.config(text=f'The Feedback has been written successfully!') # to change the label to the name
os.startfile(f'{filename}.txt') # to open the file in a new window
lfilename = Label(root,text="What do you want to call the file?", font = ("helvatica, 14"))
lfilename.grid(row=0, column=0)
filename_ent = Entry(root)
filename_ent.grid(row=1, column=0)
clicked = StringVar()
clicked.set("Who is Admin?")
drop = OptionMenu(root, clicked, "User", "#User2", "#User3", "#User")
drop.grid(row=2, column=0)
eventname = StringVar()
eventname.set("Which event was it?" )
eventname_drop = OptionMenu(root, eventname, *eventsnames, )
eventname_drop.grid(row=3,column=0, )
responsible = StringVar()
responsible.set("Who is the responsible?")
responsible_drop = OptionMenu(root, responsible, *organizerlist)
responsible_drop.grid(row=4,column=0)
responsible_drop.config(width=30, font=("helvatica", 14))
var = StringVar()
box = Checkbutton(root,text="test", variable=var, onvalue="Working", offvalue="Not Working")
box.grid(row=3,column=3)
b = Button(root, text='Done', command=run)
b.grid(row=20, column=0)
root.mainloop()

Try changing function to to below:
def run():
# getting the name
filename = filename_ent.get()
if filename == '':
# to show an error that boxes are empty
messagebox.showerror('Empty Box', 'Make sure to to fill the filename box.')
elif os.path.exists(f'{filename}.txt'):
# to show an error if the file already exists
messagebox.showerror(
'File exists', 'File already exists, try some other name not used before')
else:
# to open the file for python
new = open(f'{filename}.txt', '+w', encoding='utf-8')
# to write the name and email inside the file
new.write(f'Admin of the event: {clicked.get()}\n{responsible.get()} \n{var.get()}')
lfilename.config(text=f'The Feedback has been written successfully!') # to change the label to the name
os.startfile(f'{filename}.txt') # to open the file in a new window
In short, you forgot to call var.get() and you said box instead, which was the checkbutton itself.
Also Ive changed your second if statement to elif because having multiple if will lead to the second if getting executed, no matter what the conditions on first if was. Just try saying an empty filename with your code, and you can see the problem.
Hope this helped, do let me know if any errors or doubts.

Related

So i am making this file encrypter and decrypter, and now i am trying to make it an application using Tkinter GUI. got this error

Long ago i watched a tutorial on how to encrypt files(of any kind) with a key/password
The original code just makes the process in the terminal, but i wanted to make it into an application using tkinter as my GUI, i've come to a problem my small brain can't solve
The original video: https://www.youtube.com/watch?v=HHlInKhVz3s
This is the error i get: TypeError: Encrypt() missing 2 required positional arguments: 'WhichFile' and 'KeyInput'
This is my code:
from tkinter.filedialog import askopenfilename
import time
root = Tk()
root.title=("Tkinter Calculator")
root.geometry("500x500")
#title
WindowTitle = Label(root, text="Choose Action", font=("Arial", 15))
WindowTitle.place(x=250, y=10,anchor="center")
### The functions
#Encrypt
def Encrypt(WhichFile, KeyInput):
file = open(WhichFile, "rb")
data = file.read()
file.close()
data = bytearray(data)
for index, value in enumerate(data):
data[index] = value ^ KeyInput
file = open("CC-" + WhichFile, "wb")
file.write(data)
file.close()
#Decrypt
def Decrypt(WhichFile, KeyInput):
file = open(WhichFile, "rb")
data = file.read()
file.close()
data = bytearray(data)
for index, value in enumerate(data):
data[index] = value ^ KeyInput
file = open(WhichFile, "wb")
file.write(data)
file.close()
#Step1 - Write the name of the file(Needs to be in the same folder(Also include ext.))
WhichFile = Entry(root, width = 20)
WhichFile.place(x=100, y=150)
WhichFile.insert(0, "Enter File name with extension")
#Step2 - Ask for a key/password
KeyInput = Entry(root, width = 20)
KeyInput.place(x=100, y=250)
KeyInput.insert(0, "Enter a key: ")
#Button for encrypt
Encryptbtn = Button(root, text="Encrypt", highlightbackground='#3E4149', command=Encrypt)
Encryptbtn.place(x=100, y=350)
#Button for decrypt
Decryptbtn = Button(root, text="Decrypt", highlightbackground='#3E4149', command=Decrypt)
Decryptbtn.place(x=200, y=350)
root.mainloop()
So the error occurs in this line:
Encryptbtn = Button(root, text="Encrypt", highlightbackground='#3E4149', command=Encrypt)
Passing a function with arguments to Button's "command"
You have to pass the arguments to the function Encrypt() which demands args "WhichFile" and "KeyInput".
You can pass arguments in Button declaration by using lambda keyword:
Button(root, text="Encrypt", highlightbackground='#3E4149', command=lambda:Encrypt(file,input))
It will take the values of "file" and "input" just when you click on the button, remember it cause sometime it is not that what you actually want (e.g. Python Tkinter button callback).
If you want the arguments to be "remembered" as they was at moment of creating button, use currying
(What is 'Currying'? ,
More about "lambda").
So, for first you have to pass arguments to that function. As I can see, you slightly don't understand how it works, cause you're trying to use the arguments in declaration of a funtion like they were a global variables of something (def Encrypt(WhichFile, KeyInput) and then as an "assignment" WhichFile = Entry(...)) but it doesn't work like that, arguments that are passed to function are specified in function's call, e.g. foo(argument1,argument2), not at the moment of defining it.
Getting text from Entry :
You have to know, that WhichFile = Entry(root, width = 20) is not assigning the value of Entry to WhichFile variable, but the Entry itself (check it by using print(WhichFile)). I propose changing the name of that variable for e.g. "user_input_file" or sth.
If you want to get the text typed in the Entry use user_input_file.get().
Excatly the same thing with KeyInput Entry.
Next, you have to create a variable that will point to that value (python varaibles are pointers), and assign it in that function in a way I mentioned before (with that lambda:).
Just write it as a global variable, for example:
WhichFile = user_input_file.get()
KeyInput = user_input_key.get()
Of course after declaring user_input_file and user_input_key.
I think that'll solve ur problem, feel free to ask 'bout more.

changing label of tkinter in python

the code might be a little non-standart / messy. it's basically a guess the number game..
Any way, i want to change the label after the user pressing the yes/no button. i had some ideas but non of them worked well.. please help me :)
currently the label is "start from last time?" and i would like to change it to "choose a number between 1 - 99".
label = Label(root, text="start from last time?")
label.pack()
this is the function that activates when the user pressing the button, you can ignore what is written there just add the code :)
def yes():
fd = open("save.txt", "r")
data = fd.read()
data = data.split("|")
global answer
answer = int(data[0])
global attempts
attempts = int(data[1])
fd.close()
btnYes.pack_forget()
btnNo.pack_forget()
entryWindow.pack()
btnCheck.pack()
btnQuit.pack()
btnSave.pack()
root.geometry("500x150")
text.set("You Have {0} attempts Remaining! Good Luck!".format(attempts))
If what you are trying to do is to change the tk.Label text there are two ways to do it.
Label.config(text="Whaterver you want")
or
Label["text"] = "New Text"

How do I check if a StringVar in an Input is empty

Trying to make a button to create a file name with an input of a text variable, I'm trying to make an input that would be the "default" if the actual text box is empty, my code is as follows
def makefile():
try: prefix_text.get()
except NameError: prefix_text = None
if prefix_text is None:
prefix_text=StringVar()
prefix_text.set("Kido")
ply = open(prefix_text.get()+"_Player_.uc", "w")
ply.close()
window=Tk()
l1=Label(window, text="Prefix")
l1.grid(row=0, column=0)
prefix_text=StringVar()
e1=Entry(window, textvariable=prefix_text, width=42)
e1.grid(row=0, column=1)
b1=Button(window, text="Create File", width=12, command=makefile)
b1.grid(row=1, column=1)
window.mainloop()
MakeFile is supposed to test if the input is empty before making the file and if it is empty just set the name to be Kido, however this somehow will always cause the name to be Kido instead of the input
I've tried various things to no avail and nothing I can seem to find gives me good input on how to check if that variable is null, any help would be much appreciated!
To check if the entry is empty just check the linked variable prefix_text. Also be sure to use prefix_text.get() instead of just prefix_text.
def makefile():
global prefix_text
try: prefix_text.get()
except NameError: prefix_text = None
if not prefix_text.get().strip(): # if blank entry
prefix_text.set("Kido") # set entry
ply = open(prefix_text.get()+"_Player_.uc", "w")
ply.close()

creating a complex login and registering system in Tkinter

I am creating a program in python 3.3, whiles using tkinter, which should register the user's personal information such as their email first and second name. so far the user can register themselves and their information will be saved in a file. However, there is an error. if the user has already created an account, when they enter their login details and click "submit", the program doesnt read the file and portrays nothing. therefore, i want the program to read if the user's details exist in the file or not.
Here is my code:
def init_screen(self):
self.MainScreen.title("Sonico Services")
self.MainScreen.configure(background = "#ffff00")
self.pack(fill=BOTH, expand=1)
RegisterButton = Button(self, text="Register", bg = "red", fg = "yellow",command=self.User_Register)
RegisterButton.place(x=200,y=100)
LoginButton=Button(self,text="Login",bg="red",fg="yellow",command=self.User_Login)
LoginButton.place(x=270,y=100)
def User_Register(self):
Firstname=Label(application,text="First Name: ",bg="yellow",fg="red").grid(row=30,column=7)
Secondname=Label(application,text="Second Name: ",bg="yellow",fg="red").grid(row=30,column=10)
Emailtag=Label(application,text="Email address: ",bg="yellow",fg="red").grid(row=15,column=7)
Password=Label(application,text="Password : ",bg="yellow",fg="red").grid(row=35,column=7)
SubmitButton=Button(self,text="Submit",bg="red",fg="yellow",command=self.File_Manipulation)
SubmitButton.place(x=140,y=100)
EntryBox1=Entry(application)
EntryBox2=Entry(application)
EntryBox3=Entry(application)
EntryBox4=Entry(application)
EntryBox1.grid(row=30,column=12)
EntryBox2.grid(row=30,column=8)
EntryBox3.grid(row=15,column=8)
EntryBox4.grid(row=35,column=8)
global EntryBox1
global EntryBox2
global EntryBox3
global EntryBox4
def File_Manipulation(self):
with open("Client Data.txt","w+")as client_file:
EB=EntryBox1.get()
EB2=EntryBox2.get()
EB3=EntryBox3.get()
EB4=EntryBox4.get()
infocombo=EB +(",")+ EB2+(",")+EB3+(",")+EB4+("\n")
client_file.write(infocombo)
def User_Login(self):
Firstname=Label(application,text="First Name: ",bg="yellow",fg="red").grid(row=30,column=7)
Password=Label(application,text="Password : ",bg="yellow",fg="red").grid(row=35,column=7)
EntryBox1=Entry(application)
EntryBox4=Entry(application)
EntryBox1.grid(row=30,column=8)
EntryBox4.grid(row=35,column=8)
SubmitButton=Button(self,text="Submit",bg="red",fg="yellow",command=self.Data)
SubmitButton.place(x=140,y=100)
EB4=EntryBox4.get()
EB1=EntryBox1.get()
global EB1
global EB4
def Data(self):
data=open("Client Data.txt","w+")
read=data.readlines()
for line in read:
if (EB4+EB1) in line:
WelcomeLabel=Label(application,text="Welcome! you have successfully logged in",bg="yellow",fg="red").grid(row=30,column=10)
else:
ExitLabel=Label(application, text= "Your account does not exist, please register first",bg="yellow",fg="red").grid(row=30,column=10)
All you need to do is read the file in to your program using .readlines() and check against the list something like the below:
if (email in list_of_lines) == False: #if it passes this statement then the account doesn't already exist so we need to create a new account.
add_account()
My code will help you to create a register program using tkinter where you can store all the customers data in notepad (ie) we are using notepad as our database:
from tkinter import *
def Register():
global root
user_entry=username.get()
pass_entry=password.get()
user_data=open(user_entry + ".txt", "w")
user_data.write("Username: " + user_entry + "\n")
user_data.write("Password: " + pass_entry)
user_data.close()
username.delete(0, END)
password.delete(0, END)
Label(text="Data saved!", fg="#b0bfb6", bg="#1f1e21").pack()
def start():
root=Tk()
root.title("Register")
root.geometry("400x300")
root.resizable(0,0)
root.configure(bg="white")
global username
global password
Label(root, text="Username: ").pack()
username=Entry(root, width=25)
username.pack()
Label(root, text="Password:").pack()
password=Entry(root, width=25)
password.pack()
Button(root, text="Register", command=Register).pack()
root.mainloop()
start()

How can i make the browsed file the target for process, instead of it being hard coded in?

Instead of "mbox = ?????????" in the def start_processing(self) section, how do i make it the file that has been uploaded. This was originaly hard coded however have changed it to a file upload? Thanks
class App:
def __init__(self, master):
self.master = master
# call start to initialize to create the UI elemets
self.start()
def start(self):
self.master.title("Extract Email Headers")
self.now = datetime.datetime.now()
# CREATE A TEXT/LABEL
# create a variable with text
label01 = "Please select the .mbox file you would like to analyse"
# put "label01" in "self.master" which is the window/frame
# then, put in the first row (row=0) and in the 2nd column (column=1),
# align it to "West"/"W"
tkinter.Label(
self.master, text=label01).grid(row=0, column=0, sticky=tkinter.W)
# CREATE A TEXTBOX
self.filelocation = tkinter.Entry(self.master)
self.filelocation["width"] = 60
self.filelocation.focus_set()
self.filelocation.grid(row=1, column=0)
# CREATE A BUTTON WITH "ASK TO OPEN A FILE"
# see: def browse_file(self)
self.open_file = tkinter.Button(
self.master, text="Browse...", command=self.browse_file)
# put it beside the filelocation textbox
self.open_file.grid(row=1, column=1)
# now for a button
self.submit = tkinter.Button(
self.master, text="Execute!", command=self.start_processing,
fg="red")
self.submit.grid(row=3, column=0)
def start_processing(self):
date1= "Tue, 18 Jan 2015 15:00:37"
date2="Wed, 23 Jan 2015 15:00:37"
date1 = parser.parse(date1)
date2 = parser.parse(date2)
f = open("results.txt","w")
mbox = ????????????????????
count = 0
for msg in mbox:
pprint.pprint(msg._headers, stream = f)
tempdate = parser.parse(msg['Date'])
print(tempdate)
f.close()
print(count)
pass
def browse_file(self):
# put the result in self.filename
self.filename = filedialog.askopenfilename(title="Open a file...")
# this will set the text of the self.filelocation
self.filelocation.insert(0, self.filename)
I'm assuming you want to store the file path in a StringVar. TK uses special control variables to provide functionality for Entry objects. You can create a string control variable by calling the function tk.StringVar().
You want to create the variable when you initialize your UI, so in your start() method:
# CREATE A TEXTBOX
self.filepath = tkinter.StringVar() # This will hold the value of self.filelocation
# We set it to the "textvariable" option of the new entry
self.filelocation = tkinter.Entry(self.master, textvariable=self.filepath)
self.filelocation["width"] = 60
self.filelocation.focus_set()
self.filelocation.grid(row=1, column=0)
Now when we want to retrieve the value of it we use the get() method. In your start_processing() method:
# Here it opens the file, but you may want to do something else
mbox = open(self.filepath.get(),'r')
The way you set the value in your browse_file() method can be updated to use the control variable quite easily. Instead of inserting into the entry box directly, we'll set the value of our control variable and it will automatically update in the text entry field. In browse_file():
# this will set the text of the self.filelocation
self.filepath.set( self.filename )
Now you can properly set and retrieve the value of self.filelocation the intended way. You can change the name of self.filepath to whatever you want, of course.
For more information:
Tkinter 8.5 Reference - Control Variables
TkDocs - Tk Tutorial - Basic Widgets - Entry
I don't know for certain if mbox is supposed to be an open file, a list, a tuple, or some custom object. I'm going to assume it's an open file, since you have a function to pick a filename.
If that's the case, all you need to do is call the get method of the entry widget to get whatever the user typed:
mbox_name = self.filelocation.get()
mbox = open(mbox_name, "r")
for msg in mbox:
...

Categories