I am using a for loop to create checkbuttons based off a list. I then want a button that'll "get" which buttons have been checked or not.
Since I am not manually creating the checkbuttons, I am not naming the variables so how can I .get() whether they are on or off?
Thanks very much this worked nicely
'''
from tkinter import *
root = Tk()
shopping = ['Apples','Pears','Bananas']
chbuttonlist = []
for item in shopping:
var = StringVar()
b = Checkbutton(root,text=item,variable=var)
b.deselect()
b.pack()
chbuttonlist.append(var)
def printlist():
lst=[]
for var in chbuttonlist:
lst.append(var.get())
for i in range(len(lst)):
if lst[i]=='1':
print(shopping[i])
Button(root,text='Click to print checked items',command=printlist).pack()
root.mainloop()
'''
Related
I'm working on a project and i would like to get the Value of an Entry created in a def (turned on by a button on Tkinter)
So I have my main tkinter menu, with a button which will call the def "panier".
The def "panier" is creating the Entry "value" and another button to call a second def "calcul".
The second def "calcul" will do things with the value of Entry...
But then, in the def "calcul", when i'm trying to do value.get() it tells "NameError: name 'value' is not defined"
Here is the code, btw the Entry must be created by the def...
from tkinter import *
def panier():
value=Entry(test)
value.pack()
t2=Button(test,text="Validate",command=calcul)
t2.pack()
def calcul(value):
a=value.get()
#here will be the different calculations I'll do
test=Tk()
t1=Button(test,text="Button",command=panier)
t1.pack()
test.mainloop()
Appreciate every feedback :)
You can make the variable global like this:
from tkinter import *
def panier():
global value
value = Entry(test)
value.pack()
t2 = Button(test, text="Validate", command=calcul)
t2.pack()
def calcul():
a = value.get()
print(a)
#here will be the different calculations I'll do
test = Tk()
t1 = Button(test, text="Button", command=panier)
t1.pack()
test.mainloop()
The global value line makes the variable global so you can use it anywhere in your program.
You can also pass in the variable as an argument like what #JacksonPro suggested
t2 = Button(test, text="Validate", command=lambda: calcul(value))
This is one way to do it. Globally create a collection (list or dictionary) to hold a reference to the Entry. When you create the Entry, add it to the collection. I made it with either a list or dictionary for holding the references, so toggle the commented variations in all three places to try it both ways.
import tkinter as tk
def panier():
for item in ('value', ):
ent = tk.Entry(test)
collection.append(ent)
# collection[item] = ent
ent.pack()
t2 = tk.Button(test,text="Validate",command=calcul)
t2.pack()
def calcul():
a = collection[0].get()
# a = collection['value'].get()
print(a)
collection = []
# collection = {}
test = tk.Tk()
t1 = tk.Button(test, text="Button", command=panier)
t1.pack()
test.mainloop()
I have function that enable user to edit object and part of it is creating new window in which there are entries in checkboxes for each variable, that should by default have values of variables already typed in earlier but I can't make my checkboxes to be checked be default.
For now I'm trying to check all checkboxes by default (I think if that will work few if statements won't change it and I will have appropriate solution to my problem).
This is piece of my code related to those checkboxes:
from tkinter import *
def editonclick():
persons = ['User 1', 'User 2', 'User 3']
person_labels = []
person_checkboxes = []
checkbox_var = []
new_window = Toplevel()
for person in persons:
checkbox_var.append(IntVar(value=1))
person_labels.append(Label(new_window, text=person))
person_checkboxes.append(Checkbutton(new_window, variable=checkbox_var[-1]))
for i in range(len(persons)):
person_labels[i].grid(row=i, column=0)
person_checkboxes[i].grid(row=i, column=1)
root = Tk()
editonclick()
mainloop()
I tried setting by default checkbox_var to IntVar(value=1) setting its value to 1 after appending it to list and selecting checkbox after creating it and none of it works, but when I also printed state of this checkbox_var like this:
Attempt:
from tkinter import *
def editonclick():
persons = ['User 1', 'User 2', 'User 3']
person_labels = []
person_checkboxes = []
checkbox_var = []
new_window = Toplevel()
for person in persons:
checkbox_var.append(IntVar(value=1))
person_labels.append(Label(new_window, text=person))
print(checkbox_var[-1].get())
person_checkboxes.append(Checkbutton(new_window, variable=checkbox_var[-1]))
print(checkbox_var[-1].get())
for i in range(len(persons)):
person_labels[i].grid(row=i, column=0)
person_checkboxes[i].grid(row=i, column=1)
root = Tk()
editonclick()
mainloop()
Even though output was:
1
1
None of checkboxes were checked.
So the question is what I can do to have these checkboxes checked by default?
Edit:
I think that code above is MRE for my problem also when writting it I realized that when outside of function code works properly.
Tried also adding onvalue=1 and offvalue=0 and it also doesn't work.
The problem is that your instances of IntVar are local variables. When they go out of scope they lose their value.
A simple fix is to add global checkbox_var inside of editionclick.
The problem is that checkbox_var is a local variable and it's getting carbage collected.
You can try:
self.checkbox_var = []
person_checkboxes.append(Checkbutton(new_window, variable=self.checkbox_var[-1]))
Eventually I want to use the values in the comboboxes as parameters in other functions, but I think if I can just get them to print for now, that will be enough to build off of. Here's what I have so far.
import tkinter as tk
from tkinter import ttk
import time
def ok():
betType = betTypeVar.get()
season = seasonVar.get()
print(betType, season)
def CreateSimPreviousSeasonWindow():
prevSeasonWindow = tk.Tk()
#============= Bet Type Input =============#
betTypeVar = tk.StringVar()
betTypeLabel = tk.Label(prevSeasonWindow, text="Bet type:").grid(row=0,column=0)
betTypeChosen = ttk.Combobox(prevSeasonWindow, values=['Moneyline','Total'])
betTypeChosen.grid(row=0, column=1)
seasonVar = tk.StringVar()
seasonLabel = tk.Label(prevSeasonWindow, text='Season:').grid(row=1, column=0)
seasonChosen = ttk.Combobox(prevSeasonWindow, values=['2018', '2017'])
seasonChosen.grid(row=1,column=1)
button = tk.Button(prevSeasonWindow, text='OK', command=ok)
button.grid(row=2,column=0)
prevSeasonWindow.mainloop()
This gives me
File "C:[directory...]", line 6, in ok
betType = betTypeVar.get()
NameError: name 'betTypeVar' is not defined
To me it looks pretty obvious that this error is because ok() doesn't have any parameters passed to it, so it has no idea what 'betTypeVar' is, but all the tutorials I've read do it this way, so I'm missing something. If I try actually passing ok() the arguments, it still doesn't work.
There are two things to fix in your code. First let's focus on CreateSimPreviousSeasonWindow:
betTypeVar = tk.StringVar()
seasonVar = tk.StringVar()
You defined two StringVar but you actually never used it or linked them to your combobox object. The correct way is to set them as a textvaraible:
betTypeChosen = ttk.Combobox(prevSeasonWindow, textvariable=betTypeVar, values=['Moneyline','Total'])
seasonChosen = ttk.Combobox(prevSeasonWindow, textvariable=seasonVar, values=['2018', '2017'])
Next, NameError: name 'betTypeVar' is not defined is due to your variables being local variables. You are trying to access the same variable across different functions. To pass them around, you need to declare global:
def ok():
global betTypeVar, seasonVar
betType = betTypeVar.get()
season = seasonVar.get()
print(betType, season)
def CreateSimPreviousSeasonWindow():
global betTypeVar, seasonVar
...
Also I want to point out that if you just want to retrieve the values of the combobox, you don't really need to create two StringVar. Just combobox.get() already works good enough.
import tkinter as tk
from tkinter import ttk
import time
def ok():
global betTypeChosen, seasonChosen
print (betTypeChosen.get(), seasonChosen.get())
def CreateSimPreviousSeasonWindow():
global betTypeChosen,seasonChosen
prevSeasonWindow = tk.Tk()
#============= Bet Type Input =============#
betTypeLabel = tk.Label(prevSeasonWindow, text="Bet type:").grid(row=0,column=0)
betTypeChosen = ttk.Combobox(prevSeasonWindow,values=['Moneyline','Total'])
betTypeChosen.grid(row=0, column=1)
seasonLabel = tk.Label(prevSeasonWindow, text='Season:').grid(row=1, column=0)
seasonChosen = ttk.Combobox(prevSeasonWindow, values=['2018', '2017'])
seasonChosen.grid(row=1,column=1)
button = tk.Button(prevSeasonWindow, text='OK', command=ok)
button.grid(row=2,column=0)
prevSeasonWindow.mainloop()
CreateSimPreviousSeasonWindow()
I have a dynamically created Tkinter checkbutton widget, which takes in the contents of a list of usernames. I then displayed those names with a checkbox alongside.
What I need to do is obviously collect which usernames have been checked, so I can pass that off to another function to action.
How should I write the variable part of this so it creates a new list of chosen usernames?
What I have thus far:
def delprof_results(users_delprof):
for i in range(len(users_delprof)):
c = Checkbutton(resultsFrame, text=users_delprof[i], variable=users_delprof[i])
c.pack(anchor=W)
def delprof_del():
users_chosen = []
print str(users_delprof[i]).get() # Works up until this point. How to get individual variable with ID.
del_but = Button(resultsFrame, text="Delete", width=7, height=1, command=delprof_del)
del_but.pack(side=LEFT)
Thanks in advance,
Chris.
If you want to reach individual objects, simply keep a reference to the individual objects instead of creating objects while overwriting the same variable with each iteration of a loop like:
for i in range(30):
a = i
How to reach a's state where it was 13? Well, you can't as it's overwritten.
Instead, use collection types. In the example below I used dict:
try: # In order to be able to import tkinter for
import tkinter as tk # either in python 2 or in python 3
except ImportError:
import Tkinter as tk
def upon_select(widget):
print("{}'s value is {}.".format(widget['text'], widget.var.get()))
if __name__ == '__main__':
root = tk.Tk()
names = {"Chester", "James", "Mike"}
username_cbs = dict()
for name in names:
username_cbs[name] = tk.Checkbutton(root, text=name,
onvalue=True, offvalue=False)
username_cbs[name].var = tk.BooleanVar()
username_cbs[name]['variable'] = username_cbs[name].var
username_cbs[name]['command'] = lambda w=username_cbs[name]: \
upon_select(w)
username_cbs[name].pack()
tk.mainloop()
You could make a list of values from the checkbuttons:
values = []
for i in range(len(users_delprof)):
v = IntVar()
c = Checkbutton(master, text="Don't show this again", variable=v)
c.var = v
values.append(v)
Now you can check the value by looking in the list values, and getting the value of a checkbutton with v.get().
In Python, I have a list of names in a list data type [Person1, Person2, Person3, Person4]
Is there a way to code so that each item of the list becomes the text title of an individual checkbutton within a Tkinter Checkbutton widget which allows each name to be 'checked' as required by the user?
If possible, without importing any external modules other than Tkinter but all responses are valued
I need the checkbuttons to appear in this format:
[]Person1
[]Person2
[]Person3
[]Person4
where [] is a checkbutton that can be selected
It is possible, i would do something like:
Easiest case:
from Tkinter import *
master = Tk()
person = ["P1","P2","P3"]
result = {}
for i in person:
result[i] = Variable()
Checkbutton(master, text=i, variable=result[i]).pack()
master.mainloop()
This way all of the results go into the result dict