TKInter Python checkbutton state - python

I am trying to do some work on a text file if certain checkbuttons are checked.
"Populate CheckBoxes"
Label(master, text="Pick at least one index:").grid(row=4, column=1)
Checkbutton(master, text="Short",variable=var1).place(x=5,y=60)
Checkbutton(master, text="Standard",variable=var2).place(x=60,y=60)
Checkbutton(master, text="Long",variable=var3).place(x=130,y=60)
Calling
print("Short: %d,\nStandard: %d,\nLong: %d" % (var1.get(), var2.get(),
var3.get()))
prints out 0 or 1 for each variable but when I am trying to use that value to do something it does'nt seem to call the code.
if var2.get(): <--- does this mean if = 1?
Do something

In below example var.get()'s value is printed in command prompt if it's False and updates the lbl['text'] if it's True:
import tkinter
root = tkinter.Tk()
lbl = tkinter.Label(root)
lbl.pack()
var = tkinter.BooleanVar()
def update_lbl():
global var
if var.get():
lbl['text'] = str(var.get())
else:
print(var.get())
tkinter.Checkbutton(root, variable=var, command=update_lbl).pack()
root.mainloop()
But below code never prints as "0" and "1" are both True:
import tkinter
root = tkinter.Tk()
lbl = tkinter.Label(root)
lbl.pack()
var = tkinter.StringVar()
def update_lbl():
global var
if var.get():
lbl['text'] = str(var.get())
else:
print(var.get())
tkinter.Checkbutton(root, variable=var, command=update_lbl).pack()
root.mainloop()

Related

How to set the text in tkinter?

I want to set the answer using the set() method without writing it in the text attribute in the Label and also I want to change the message without displaying the messages over each other.
I want the new message to appear and the one before it to disappear. I tried to use the set() and get() methods but it used to return its default value without using the value in the set() method and I don't know why.
from tkinter import *
from tkinter import messagebox
from PIL import ImageTk,Image
root= Tk()
root.title("Project")
root.geometry('500x600')
root.title('Choose Answer')
var = IntVar()
textt = StringVar()
print(textt.set('Clicked..........'))
def Result():
print(textt.set('You Clicked....................'))
if(var.get() == 1):
print(var.get())
print(textt)
textt.set('You Clicked')
resultText = Label(root, text=textt , fg='white',bg='gray', width=40)
resultText.place(x=100,y=200)
else:
textt.set('You did\'t Click')
resultText = Label(root, text=textt, fg='white',bg='grey', width=40)
resultText.place(x=100,y=200)
checkBox = Checkbutton(root, text='Did you Study Math', variable=var, bg='grey')
checkBox.place(x=50,y=50)
button = Button(root, text='Select', fg='white', bg='grey',font='sans-serif',command=Result)
button.place(x=50,y=100)
root.mainloop()
This should work:
from tkinter import *
root = Tk()
root.title("Project")
root.geometry('500x600')
root.title('Choose Answer')
var = IntVar()
textt = StringVar()
resultText = Label(root, textvariable=textt , fg='white',bg='gray', width=40)
resultText.place(x=100,y=200)
def Result():
print(var.get())
if var.get() == 1:
textt.set('You Clicked')
else:
textt.set('You didn\'t Click')
checkBox = Checkbutton(root, text='Did you Study Math', variable=var, bg='grey')
checkBox.place(x=50,y=50)
button = Button(root, text='Select', fg='white', bg='grey',font='sans-serif',command=Result)
button.place(x=50,y=100)
root.mainloop()
When you create resultText, instead of setting the text argument to textt, you need to set the textvariable argument to text. That way, the text of the variable is automatically changed when you change textt.
I removed all the lines where resultText was recreated and re-placed, and just created it once before defining Result(). Also, I removed from tkinter import messagebox, because you already import it when you call from tkinter import *. Just a note: wildcard imports are discouraged, so try to avoid using them in the future.

cannot know if checkbox was checked or not

I'm a having a problem that I can't check if the checkbutton in tkinter is checked or not (I always get False).
I'm sure I'm missing something but I've tried for so long and I don't know what I'm doing wrong.
Bellow is the minimum code I could write that shows the problem:
There are two files:
The main file (that you run) is called "main_GUI.py" and here's the code:
from tkinter import *
import sub_GUI
root = Tk()
button1 = Button(root, bg='white', text="Click me", font=("Helvetica",12),
height=3, width=25, command=sub_GUI.create_new_window)
button1.grid(column=1, row=1)
root.mainloop()
The second file is called "sub_GUI.py" and here's the code:
from tkinter import *
var1 = None
sub_root = None
def create_widgets():
global sub_root
global var1
var1 = BooleanVar()
Checkbutton(sub_root,
text="A",
variable=var1,
command=do_something
).grid(row=2, column=0, sticky=W)
def do_something():
global var1
is_current_joint_checked = var1.get()
if is_current_joint_checked:
print('True')
else:
print('False')
def create_new_window():
global sub_root
sub_root = Tk()
sub_root.title("Movie Chooser")
create_widgets()
The problem is that in the window that appears with the letter 'A' (after you clicked the button), every time I check/uncheck 'A' it prints False (never prints True).
Can anyone tell me what's the problem?
Thanks

How to overwrite data in text file in tkinter

I am creating a program with tkinter which comes with a default name and password stored in a text file. After login you need to open the Toplevel window and type in the name and password you want to use in your subsequent logins. I have defined my variables but if I want to overwrite the text file I receive the below:
Error "NameError: name 'e1' is not defined"
Which I know I have defined.
import sys
from tkinter import messagebox
from tkinter import *
now = open("pass.txt","w+")
now.write("user\n")
now.write("python3")
now.close()
def login_in():
with open("pass.txt") as f:
new = f.readlines()
name = new[0].rstrip()
password = new[1].rstrip()
if entry1.get() == name and entry2.get() == password:
root.deiconify()
log.destroy()
else:
messagebox.showerror("error","login Failed")
def change_login():
ch = Toplevel(root)
ch.geometry('300x300')
e1 = Entry(ch, width=20).pack()
e2 = Entry(ch, width=20).pack()
sb = Button(ch, text="save", command=save_changes).pack()
def save_changes(): # function to change data in the txt file
data = e1.get() + "\n " + e2.get()
with open("pass.txt", "w") as f:
f.writelines(data)
root= Tk()
log = Toplevel()
root.geometry("350x350")
log.geometry("200x200")
entry1 = Entry(log)
entry2 = Entry(log)
button1 = Button(log, text="Login", command=login_in) #Login button
entry1.pack()
entry2.pack()
button1.pack()
label = Label(root, text="welcome").pack()
butt = Button(root, text="change data in file", command=change_login).pack()
root.withdraw()
root.mainloop()
So you have a few options here but in general you have 2 major issues.
The first issue is the use of .pack() after the creation of your e1 and e2 entry fields. This is a problem for the get() method as the geometry manager will return None if you pack this way. The correct method is to create the widget first with e1 = Entry(ch, width=20) and then pack it on the next line with e1.pack() this will allow get() to work on e1.
The second issue is the matter of local variables vs global variables. You have created e1 and e2 inside of the function change_login() and without telling python that e1 and e2 are global variables it will automatically assume you want them as local variables. This means the variables are only accessible from within the function they are created in.
You have a few options and I will break them out for you.
1) The quick and dirty option is to assign e1 and e2 as global variables. This can be done by using global var_name, var2_name, and_so_on so in this case add this line to the top of your change_login(): and save_changes() functions:
global e1, e2
This well tell python to add e1 and e2 to the global name space and it will allow save_changes() to work with the variables in the global name space.
2) Another method is to pass the 2 variables to save_changes() using the button command. We will need to use lambda for this and we can accomplish this by adding:
command = lambda e1=e1, e2=e2: save_changes(e1, e2)
to the button created in change_login() and adding the 2 arguments to save_changes() like this:
save_changes(e1, e2)
This will work just as well as the first option and it also avoids the use of global variables.
3) A third option is to create the entire program as a class and to use class attributes to allow the variables to work with all methods within the class.
Below is an example of your code using the 1st option:
import sys
from tkinter import messagebox
from tkinter import *
now = open("pass.txt","w+")
now.write("user\n")
now.write("python3")
now.close()
def login_in():
with open("pass.txt") as f:
new = f.readlines()
name = new[0].rstrip()
password = new[1].rstrip()
if entry1.get() == name and entry2.get() == password:
root.deiconify()
log.destroy()
else:
messagebox.showerror("error","login Failed")
def change_login():
global e1, e2
ch = Toplevel(root)
ch.geometry('300x300')
e1 = Entry(ch, width=20)
e1.pack()
e2 = Entry(ch, width=20)
e2.pack()
sb = Button(ch, text="save", command=save_changes).pack()
def save_changes(): # function to change data in the txt file
global e1, e2
data = e1.get() + "\n" + e2.get() # removed space after \n
with open("pass.txt", "w") as f:
f.writelines(data)
root= Tk()
log = Toplevel()
root.geometry("350x350")
log.geometry("200x200")
entry1 = Entry(log)
entry2 = Entry(log)
button1 = Button(log, text="Login", command=login_in) #Login button
entry1.pack()
entry2.pack()
button1.pack()
label = Label(root, text="welcome").pack()
butt = Button(root, text="change data in file", command=change_login).pack()
root.withdraw()
root.mainloop()
Below is an example of your code using the 2nd option:
import sys
from tkinter import messagebox
from tkinter import *
now = open("pass.txt","w+")
now.write("user\n")
now.write("python3")
now.close()
def login_in():
with open("pass.txt") as f:
new = f.readlines()
name = new[0].rstrip()
password = new[1].rstrip()
if entry1.get() == name and entry2.get() == password:
root.deiconify()
log.destroy()
else:
messagebox.showerror("error","login Failed")
def change_login():
ch = Toplevel(root)
ch.geometry('300x300')
e1 = Entry(ch, width=20)
e1.pack()
e2 = Entry(ch, width=20)
e2.pack()
Button(ch, text="save", command=lambda e1=e1, e2=e2: save_changes(e1, e2)).pack()
def save_changes(e1, e2): # function to change data in the txt file
data = e1.get() + "\n" + e2.get() # removed space after \n
with open("pass.txt", "w") as f:
f.writelines(data)
root= Tk()
log = Toplevel()
root.geometry("350x350")
log.geometry("200x200")
entry1 = Entry(log)
entry2 = Entry(log)
button1 = Button(log, text="Login", command=login_in) #Login button
entry1.pack()
entry2.pack()
button1.pack()
label = Label(root, text="welcome").pack()
butt = Button(root, text="change data in file", command=change_login).pack()
root.withdraw()
root.mainloop()
Below is an example of your code converted to a class and using class attributes to avoid the use of global variables.
import sys
from tkinter import messagebox
from tkinter import *
class MyApp(Frame):
def __init__(self, master, *args, **kwargs):
Frame.__init__(self, master, *args, **kwargs)
self.master = master
self.master.withdraw()
self.log = Toplevel()
self.master.geometry("350x350")
self.log.geometry("200x200")
self.entry1 = Entry(self.log)
self.entry2 = Entry(self.log)
self.button1 = Button(self.log, text="Login", command=self.login_in)
self.entry1.pack()
self.entry2.pack()
self.button1.pack()
Label(root, text="welcome").pack()
Button(root, text="change data in file", command=self.change_login).pack()
def login_in(self):
with open("pass.txt") as f:
new = f.readlines()
name = new[0].rstrip()
password = new[1].rstrip()
if self.entry1.get() == name and self.entry2.get() == password:
self.master.deiconify()
self.log.destroy()
else:
messagebox.showerror("error","login Failed")
def change_login(self):
ch = Toplevel(self.master)
ch.geometry('300x300')
self.e1 = Entry(ch, width=20)
self.e1.pack()
self.e2 = Entry(ch, width=20)
self.e2.pack()
Button(ch, text="save", command=self.save_changes).pack()
def save_changes(self):
data = "{}\n{}".format(self.e1.get(), self.e2.get())
with open("pass.txt", "w") as f:
f.writelines(data)
if __name__ == "__main__":
now = open("pass.txt","w+")
now.write("user\n")
now.write("python3")
now.close()
root = Tk()
app = MyApp(root)
root.mainloop()

Tkinter python: issue with clearing out the widget

Someone please help me figure this out.
I have the following problem in Tkinter Python. The problem is that the text is overlaying with the previous text. and/or is copying below that.
I've tried to use label.config(root).pack() instead of Label(root, text="").pack()
This kinda solves the problem it starts to write over the previous text but there are 2 problems with this.
1: the text old text/Entrys all still there, it just overlays.
2: this only works with label.config, and I would also like this to work with buttons and Entrys(textbox)
I've also tried .pack_forget() and .destroy() but unfortunately it did nothing.
CODE
from tkinter import *
import pickle
import time
import os
def new_profile():
global Var1, Var2
var1 = StringVar()
var2 = StringVar()
Label(root, text="Create a new profile").pack()
Label(root, text="User Name").pack()
Entry(root, textvariable=var1).pack()
Label(root, text="Password").pack()
Entry(root, textvariable=var2).pack()
Button(root, text="Create", command=create_profile).pack()
Var1, Var2 = var1, var2
return
def create_profile():
text1 = Var1.get()
text2 = Var2.get()
print(text1)
dict = {}
dict['Name'] = text1
dict['Password'] = text2
pickle.dump(dict, open("test.txt", "wb"))
dict1 = pickle.load(open("test.txt", "rb"))
if dict1['Name'] == text1 and dict1['Password'] == text2:
Label(root, text="").pack()
Label(root, text="Profile creation successful", ).pack()
Label(root, text="Name:" + " " + text1).pack()
Label(root, text="Password:" + " " + text2).pack()
else:
Label(root, text="Something went wrong while creating your profile.", ).pack()
return
def load_profile():
select = "Load profile.."
label.config(text=select)
return
root = Tk()
root.geometry("500x400+300+300")
root.title("client")
menubar = Menu(root)
filemenu = Menu(menubar, tearoff=0)
filemenu.add_command(label="New Profile", command=new_profile)
filemenu.add_command(label="Load Profile", command=load_profile)
menubar.add_cascade(label="Profile Options", menu=filemenu)
root.config(menu=menubar)
label = Label(root)
label.pack()
root.mainloop()
create a array such as
on_screen = []
at the start then name your widgets and and add them to the array
password_label = Label(root, text="Password").pack()
password = Entry(root, textvariable=var2).pack()
on_screen.append(password)
on_screen.append(password_label)
then use a for loop to destroy all the widgets in the array
for w in on_screen:
w.destroy()

Trouble importing a module with radiobuttons - python

Hi I have made a program that runs various other programs. I import the module and it works fine for programs that don't have radiobuttons involved. The programs with radiobuttons work fine when they are ran by themselves. When they are ran through my menu program, the radiobuttons do not give the IntVar values. Anybody have any ideas on how to fix this? The modules are my ow programs but they all use Tkinter. Here is the code for the menu:
from Tkinter import *
def cmd():
if var.get() == 1:
import animal_age_calculator
animal_age_calculator.createDisplay()
if var.get() == 2:
import temperatureCalculator
temperatureCalculator.createDisplay()
if var.get() == 3:
import calculator
calculator.createDisplay()
if var.get() == 4:
import currencyConverter
currencyConverter.createDisplay()
def createDisplay():
global var
root = Tk()
root.title('Calculator')
title = Label(root, text='Please Select which Calculator you would like to use', font=50)
title.grid(row=0, column=0)
calcType = Frame(root)
calcType.grid(row=1, column=0)
var = IntVar()
animal = Radiobutton(calcType, text='Animal Age Calculator', variable=var, value=1)
animal.pack()
tempConverter = Radiobutton(calcType, text='Temperature Calculator', variable=var, value=2)
tempConverter.pack()
calc = Radiobutton(calcType, text='Calculator', variable=var, value=3)
calc.pack()
currency = Radiobutton(calcType, text='Currency Converter', variable=var, value=4)
currency.pack()
select = Button(root, text='Go', command=cmd)
select.grid(row=2, column=0)
root.mainloop()
if __name__ == '__main__':
createDisplay()
Here is the code for one of the radiobutton programs:
from Tkinter import *
def convert(temperature):
global var4
a = var4.get()
print(str(a))
if a == 1:
print 'test2'
display.delete(1.0, END)
finalTemp = int(temperature)*1.8+32
finalTemp = round(finalTemp, 1)
display.insert(INSERT, finalTemp)
if a == 2:
display.delete(1.0,END)
finalTemp = int(temperature)-32/1.8
finalTemp = round(finalTemp, 1)
display.insert(INSERT, finalTemp)
def createDisplay():
global display, var4
root = Tk()
root.title('Temperature Converter')
root.resizable(width=False, height=False)
title = Label(root, text="Welcome to the temperature converter", font=36)
title.grid(row=0, column=1, columnspan=3)
selTemp = LabelFrame(root, text="Please select your temperature")
selTemp.grid(row=1, column=2)
temp = Scale(selTemp, orient=HORIZONTAL, sliderlength=20, from_=0, to=250, length=250, command=convert)
temp.pack()
temperature = temp.get()
displayFrame = LabelFrame(root, text="Your converted temperature is")
displayFrame.grid(row=1, column=3)
display = Text(displayFrame, width=6, height=1)
display.pack()
var4 = IntVar()
tempType = LabelFrame(root, text='Please select your temperature you would like to convert')
tempType.grid(row=1, column=1)
celcius = Radiobutton(tempType, text="Celcius", variable=var4, value=1)
celcius.pack()
fahrenheit = Radiobutton(tempType, text="Fahrenheit", variable=var4, value=2)
fahrenheit.pack()
root.mainloop()
if __name__ == '__main__':
createDisplay()
The crux of the problem is that you're creating two instances of Tk. You can't do that. Tkinter is designed for you to only ever create a single instance of Tk at any one time. Your modules should create instances of Toplevel rather than instances of Tk, and they should not create a new event loop when the module is imported.

Categories

Resources