storing checkboxes into a list tkinter - python

I am fairly new to tkinter was able to get the following code.
from tkinter import *
from tkinter import filedialog
master = Tk()
v = IntVar()
v.set(1)
var1 = IntVar()
var2 = IntVar()
var3 = IntVar()
CategorySubmit= IntVar()
my_list = [{"Kitchen":var1},{"Electric Supply":var2},{"Books":var3}]
def get_boxes(value):
#store the checked boxes for later use
pass
def get_value(value):
#print(value)
if value=="Category":
for widget in master.winfo_children():
widget.destroy()
row =1
for i in my_list:
Checkbutton(master, text=list(i.keys())[0], variable=list(i.values())[0]).pack()
row+=1
Button(master, text="Submit", variable=CategorySubmit,command=get_boxes).pack()
#save the check boxes made by user into a list then quit master
else:
file_chosen =filedialog.askopenfilename(title='Please Select Input File', filetypes=[('Excel files', ('.xlsx', '.csv', '.xls', 'xlsm'))])
print(f"Done: {file_chosen}")
master.destroy()
MODES = [
("Choice 1","ID"),
("Choice 2","Category"),
("Choice 2","Full"),
]
choice_made= StringVar()
choice_made.set('Choice 1')
for text,mode in MODES:
Radiobutton(master,text=text,variable=choice_made,value=mode).pack()
but = Button(master,text="Submit",command=lambda: get_value(choice_made.get()))
but.pack()
master.mainloop()
print(file_chosen) #gives undefined error ?
I need to store the values in checkboxes into a list so I can use later. also I have an error when for the variable name outside the master.mainloop() , it gives NameError: name 'file_chosen' is not defined,
My idea is when "Choice 1" or "Choice 3" are picked a fileprompt is given so I can continue with my script later on, else if "Choice 2" 3 checkboxes that I store in a list

The file_chosen variable is local inside the get_value() function. To extend its scope you have to declarate as global:
def get_value(value):
global file_chosen

Related

Use loop to create x number of tkinter OptionMenu

I am attempting to create an arbitrary number of optionmenus, but have trouble when trying to pull the StringVar() selected by each optionmenu.
Goal: Create an arbitrary number of optionmenus with consecutive names (up to that arbitrary number) and consecutive variable names keeping track of the current optiomenu value
For example if an optionmenu is as follows:
import tkinter as tk
from tkinter import *
root = tk.Tk()
root.geometry()
dropdown1 = StringVar()
Dropdownoptions = [
"option1",
"option2",
"option3"
]
dropdownfirst = tk.OptionMenu(root, dropdown1, *Dropdownoptions)
dropdownfirst.grid(column=0, row=0)
root.mainloop()
If using a dictionary I do not know how to pull the values out of each Optionmenu. When looking at other questions about the use of dictionaries to create variables, most answers boil down to "Learn How to Use Dictionaries" instead of answering the questions.
There was a very similar problem posted in Tkinter Create OptionMenus With Loop but sadly it is not applicable in my case.
New code with grid and non-working button:
import tkinter as tk
def erase_option():
for (name, var) in options.items():
print(var.get())
# print(options['optionmenu4'])
# This just places label over dropdown, doesnt successfully take place for removal
labelforemoval = tk.Label(text=" ")
labelforemoval.grid(column=0, row=4)
labelforemoval.grid_forget()
root = tk.Tk()
Dropdownoptions = [
"option1",
"option2",
"option3"
]
maxval = 10
options = {}
for om, x in zip(range(maxval), range(maxval)):
name = f"optionmenu{om}"
var = tk.StringVar()
options[name] = var
name = tk.OptionMenu(root, var, *Dropdownoptions)
name.grid(column=0, row=x)
button = tk.Button(root, text="Erase 5th option", command=erase_option)
button.grid(column=0, row=maxval)
root.mainloop()
Give each optionmenu its own StringVar instance. Save those instances in a list or dictionary. To get the values, iterate over the list.
The following code creates a dictionary named options. It creates a series of variables and optionmenus in a loop, adding each variable to this options dictionary. The function print_options iterates over the list printing out the key and value for each option.
import tkinter as tk
def print_options():
for (name, var) in options.items():
print(f"{name}: {var.get()}")
root = tk.Tk()
Dropdownoptions = [
"option1",
"option2",
"option3"
]
options = {}
for om in range(10):
name = f"Option {om}"
var = tk.StringVar(value="")
options[name] = var
om = tk.OptionMenu(root, var, *Dropdownoptions)
om.pack()
button = tk.Button(root, text="Print Options", command=print_options)
button.pack(side="bottom")
root.mainloop()

looping check button and getting its value

Creating check-button using for loop and extracting the value (whether it is checked or unchecked)
Hello all,
I am a beginner to python GUI and planning to create a GUI with many check-buttons and write the value of each check-button in a text file on clicking a submit button.
from tkinter import *
import tkinter as tk
fields_output=["option 01","option 02","option 03","option 04","option 05","option 06","option 07","option 08","option 09","option 10","option 11"]
def my_function_01():
f = open("C:\\Users\\atulh\\Desktop\\Atul_Python\\demofile2.txt", "a")
f.write("Following is the summary !")
f.write("\n")
r=0
for each_field in fields_output:
f.write(each_field + " = " )
f.write("\n")
f.close()
root = tk.Tk()
frame_lh =LabelFrame(root, text="Field Outputs")
frame_lh.grid(row=1, sticky=W)
r=0
for each_field in range(len(fields_output)):
tk.Checkbutton(frame_lh,text=fields_output[each_field],).grid(row=r, sticky=W)
r=r+1
b = tk.Button(root,text="Submit_data",command=my_function_01()).grid(row=1,column=1)
A few things:
Import tkinter only once. Several imports of the same module may become confusing. Importing as tk is the usual way.
To get the states of the Checkbuttons you'll have to associate each one with a variable, and then save references to all these variables. I have saved them to a dictionary with the field as key.
I changed the for loop to be more Pythonic. The loop is over the fields_output list and the enumerate() function generates the index starting from 0.
In the loop I associate each Checkbutton with a BooleanVar() and save a reference to the button_dict. Later the my_function_01() uses the button_dict to get the states of all the Checkbuttons.
Added root.mainloop() at the end. If you are developing the program in IDLE the program will work regardless using the mainloop in IDLE. But the program may not run outside your development environment.
I changed the file path and the options list.
import tkinter as tk
fields_output = ["option 01", "option 02", "option 03", "option 04"]
def my_function_01():
f = open("demofile2.txt", "a")
f.write("Following is the summary !")
f.write("\n")
for field in fields_output:
f.write(field + " = " + str(button_dict[field].get()))
f.write("\n")
f.close()
root = tk.Tk()
frame_lh = tk.LabelFrame(root, text="Field Outputs")
frame_lh.grid(row=0, column=0, sticky=tk.W, padx=10, pady=10)
button_dict = {}
for index, field in enumerate(fields_output):
var = tk.BooleanVar() # Create a variable for each Checkbutton
c = tk.Checkbutton(frame_lh, text=field, variable=var)
c.grid(row=index, sticky=tk.W)
button_dict[field] = var # save reference to the variable
b = tk.Button(root, text="Submit_data", command=my_function_01)
b.grid(row=0, column=1, padx=10, pady=10)
root.mainloop()

Using python tkinter library, how to write a function that checks if a textbox is checked?

I'm trying to see what checkbox are checked and write a if/else function to do stuff. The number of check boxes depends on the number of topics I parse into the program and create a checkbox for each item.
I added:
chk_state = IntVar()
But this is only good if you are using one checkbox.
I am using a list to generate all my checkboxes:
Which generates these variables for each checkbox:
'chk0', 'chk1', 'chk2', 'chk3', 'chk4', 'chk5', 'chk6', 'chk7', 'chk8', 'chk9', 'chk10', 'chk11', 'chk12', 'chk13', 'chk14', 'chk15', 'chk16', 'chk17', 'chk18', 'chk19', 'chk20', 'chk21', 'chk22', 'chk23', 'chk24']
from tkinter import *
from tkinter import messagebox
from reader import openit
import sys
data = openit(sys.argv[1])
window = Tk()
#set size of window
window.geometry('850x400')
window.title("Chose Your ROS Topic" )
lbl = Label(window, text="Topics", font=("Arial Bold", 25))
lbl.grid(column=0,row=0)
#check checkbox value boolean
chk_state = IntVar()
#chk_state.set(0) #uncheck
#chk_state.set(1) #checked
#Looping through list and adding each one as a checked button
counter = 0
selected_list = []
for x in data.split(","):
# global selected_list
#print(x)
#print(counter)
name = "chk" + str(counter)
# appends each checkbox name to a list
selected_list.append(name)
name = Checkbutton(window, text='%s' % x , font=(15), onvalue=1, offvalue=0, variable=chk_state)
if counter == 0:
name.grid(column=1, row=1)
#print('only for counter 0')
else:
name.grid(column=1, row=1+counter -1)
#print("the rest")
counter += 1
#After selecting all the topics you want to graph
def topics_selected():
#messagebox.showinfo('Topics picked', 'graphing all your checked topics')
#for topics in
if chk_state.get():
print("some checked topics")
else:
print("Nothing is checked")
# Adding input tkinter textbox
txt = Entry(window,width=10)
txt.grid(column=1,row=0)
# Function that changes buttond
def inputcheck():
res = "Topics picked " + txt.get()
lbl.configure(text = res)
def clicked():
lbl.configure(text="Parser was clicked, checking rosbag")
# Adding button widget
btn = Button(window, text="ROS topic parser", bg="orange", fg="black", command=topics_selected)
btn.grid(column=2, row=1)
#Create a checkbox
#chk = Checkbutton(window, text='Choose')
#chk.grid(column=0, row=4)
window.mainloop()
if __name__ == "__main__":
pass
#print(data)
I want to be able to add whatever was selected to a list and push that list to another function.
You need to create a tkinter variable for each Checkbutton. Right now all you Checkbutton shares the same variable chk_state.
To make this work, simply move your definition of IntVar inside the for loop:
...
selected_list = {} #use a dict to store name/IntVar pair; can use a list also
for num, x in enumerate(data.split(",")): #use enumerate to get a num count
chk_state = IntVar() #create a new IntVar in each iteration
selected_list[num] = chk_state #save name/IntVar pair
name = Checkbutton(window, text='%s' % x , font=(15), onvalue=1, offvalue=0, variable=chk_state)
if num == 0:
name.grid(column=1, row=1)
else:
name.grid(column=1, row=1+num-1)
#After selecting all the topics you want to graph
def topics_selected():
if any(s.get() for s in selected_list.values()): #check if any checkbutton is checked
print ("some checked topics")
print ([s.get() for s in selected_list.values()])
else:
print("Nothing is checked")
You could use tk.BooleanVar for each of your check boxes, and set their values inside a for loop.
Keeping the variables in a list allows you to pass the selection to a function.
import tkinter as tk
DEFAULTS = [True, False, False, False]
def display_selected_options(options, values):
for option, value in zip(options, values):
print(f'{option}: {value.get()}')
def create_option_selectors(frame, options, option_variables) -> None:
for idx, option in enumerate(options):
option_variables[idx].set(DEFAULTS[idx])
tk.Checkbutton(frame,
variable=option_variables[idx],
onvalue=True,
offvalue=False,
text=option,
).pack(side=tk.LEFT)
root = tk.Tk()
options = ['chk0', 'chk1', 'chk2', 'chk3']
option_variables = [tk.BooleanVar(root) for _ in range(len(options))]
frame = tk.Frame(root)
create_option_selectors(frame, options, option_variables)
frame.pack()
display_options = tk.Button(root, text='validate', command=lambda options=options,
values=option_variables: display_selected_options(options, values))
display_options.pack()
root.mainloop()
Alternatively, you could use a dictionary to store the option -> value pairs:

Updating values in a list from a Tkinter entry box - Python

I am trying to update the values in a list from values that are entered into an entry box created in TKinter. In my example the user enters the real name of the people in a list. Their real name will replace the 'x' in the example_list.
I have specified the variable as global in the method but the change only applies to the second value iterated in the list - the first is the initialised value - 99 in the code below.
I have also tried to specify a lambda function that updates i[1] individually, however this does not work - bad syntax. Besides the quit() function seems to be the only way to continue the iteration.
Is there a way to do this cleanly and with the first item in the list updated?
from Tkinter import *
example_list = [['Jimmy Bob','x','78'],[" Bobby Jim",'x','45'] ,["Sammy Jim Bob",'x','67'] ] #Nickname/Real Name/Age
newValue = 99
def replace():
global newValue
newValue = e1.get()
print("Their real name is %s" %(e1.get()))
#return(newValue)
win.quit()
root = Tk()
for i in example_list:
win = Toplevel(root)
#win.lift()
e1 = Entry(win)
e1.grid(row=1, column=0)
var = StringVar()
var.set(i[0])
Label(win, textvariable = var).grid(row=0, column=0)
Button(win, text='Enter Real Name', command=replace).grid(row=2, column=0, pady=4)
#Button(win, text='Enter Real Name', command=lambda: i[1] =replace()).grid(row=2, column=0, pady=4)
i[1] = newValue
win.mainloop( )
root.mainloop()
for i in example_list:
print(i)
Thanks to Wayne Werner who directed me towards the tksimpledialog, the solution to the problem is here.
from Tkinter import *
import tkSimpleDialog
example_list = [['Jimmy Bob','x','78'],[" Bobby Jim",'x','45'] ,["Sammy Jim Bob",'x','67'] ]
root = Tk()
root.geometry("400x400")
Label(root, text = "Enter the names in the dialog").grid(row=0, column=0)
for i in example_list:
root.lower()
i[1] = tkSimpleDialog.askstring('Enter their real name', 'What is %s real name' %i[0])
print(i[1])
root.mainloop()

Tkinter Program for making a calculator

I am trying to make a simple GUI calculator just for addition/subtraction in the beginning. I am able to print the result to the console but I want to print it to the Entry box like the First Name entry box for example but not able to do it. I would really appreciate if you could help.(*Please neglect the alignment right now of the buttons I am focusing on the functioning, trying to get it right)
from Tkinter import *
import tkMessageBox
import sys
class scanner:
list1 = []
def __init__(self,parent):
self.entrytext = StringVar()
self.entrytext1 = StringVar()
Label(root, text="first name", width=10).grid(row=0,column=0)
Entry(root, textvariable=self.entrytext, width=10).grid(row=0,column=1)
Label(root, text="last name", width=10).grid(row=1,column=0)
Entry(root, textvariable=self.entrytext1, width=10).grid(row=1,column=1)
Button(root, text="ADD", command=self.add).grid()
Button(root, text="SUBTRACT", command=self.subtract).grid()
def add(self):
global a
global b
self.a=int(self.entrytext.get())
self.b=int(self.entrytext1.get())
print "result is", self.a+self.b
def subtract(self):
global a
global b
self.a=int(self.entrytext.get())
self.b=int(self.entrytext1.get())
print "result is", self.a-self.b
root= Tk()
root.geometry("300x300")
calc = scanner(root)
root.mainloop()
If you want to show the result of the operation as a label's text, just create a new label and configure it with the text option and the string you are printing as its value. As a side note, you don't need the global statements, and the use of instance variables is not necessary either. However, it is very important to check that the content of the entries are actually valid numbers:
def __init__(self,parent):
# ...
self.result = Label(root, text='')
self.result.grid(row=4, column=0)
def add(self):
try:
a = int(self.entrytext.get())
b = int(self.entrytext1.get())
self.result.config(text=str(a+b))
except ValueError:
print("Incorrect values")
To add entry text to the widget, use the insert method. To replace the current text, you can call delete before you insert the new text.
e = Entry(master)
e.pack()
e.delete(0, END)
e.insert(0, "a default value")
The first parameter in the delete method is which number character to delete from and the second parameter is where to delete too. Notice how END is a tkinter variable.
The parameters for the insert function is where the text will be inserted too, and the second parameter is what will be inserted.
In the future, I recommend going to Effbot and reading about the widget that you are trying to use to find out all about it.

Categories

Resources