I am storing a matrix of Entries, each attached to a unique StringVar. On the callback for the StringVar, I want to be able to find which StringVar it was, with respect to the matrix. This is what I have:
def callback(sv, index):
print index
for i in range(ncols):
for j in range(self.nrows):
sv = StringVar()
uniqueId = str(i)+str(j)
sv.trace("w", lambda name, index, mode, sv=sv: callback(sv, uniqueId))
self.results[i][j] = Entry(gridtable,textvariable=sv,bg='grey',borderwidth=1,fg='black',width=self.widget_width).grid(row=j+2,column=i+1,sticky='ew')
However, it always prints the same index ('718' - which is '7'+'18': the values that i and j stop at). How can I get a unique identifier for these StringVars?
The sv variable is changing in your code, but uniqueID is getting stuck at the last value it's given. You can set it to remember its value on that iteration of the loop by including it in the lambda expression, like this:
from Tkinter import *
def callback(var, index):
print var, index
root = Tk()
for i in range(10):
var = StringVar()
uniqueID = i
var.trace('w', lambda name,index,mode, var=var, uniqueID=uniqueID: callback(var, uniqueID))
Entry(root, textvariable=var).pack()
mainloop()
Related
Hi i am trying to print the sum of the numbers that will be written in the entry boxes but I think there is a problem with changing list into int form. I keep getting this error
TypeError: int() argument must be a string, a bytes-like object or a number, not 'Entry'
from tkinter import *
window = Tk()
window.title=("card")
window.geometry('1500x100')
entries = []
def total():
for entry in entries:
global sum
sum = sum + int(entry)
e1.insert(0,sum)
for i in range(10):
en = Entry(window)
en.grid(row=1, column=0+i)
entries.append(en)
b1=Button(window,text="dsf",command=total).grid(row=7,column=1)
e1=Entry(window).grid(row=20,column=2)
window.mainloop()
Your code have multiple issues,see code below.
import tkinter as tk #dont use wildcard imports to avoid name conflicts
window = tk.Tk()
window.title=("card")
window.geometry('1500x100')
entries = []
def total():
summa = 0 #dont use reserved names like sum or all
for entry in entries:
summa += int(entry.get())#+entrys content as int
e1.delete(0, 'end')#clear entry
e1.insert(0,summa)
for i in range(3):
en = tk.Entry(window)
en.grid(row=1, column=0+i)
entries.append(en)
b1=tk.Button(window,text="dsf",command=total)#split construction
b1.grid(row=7,column=1)#######################from geometry method
e1=tk.Entry(window)
e1.grid(row=20,column=2)
window.mainloop()
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 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().
I have a list of tkinter entry fields generated dynamically. I need to grab the contents of each field while knowing what it's referring to. I have tried adding something like "entry"+count = Entry(..) but as expected it wont work like that and is really quite a stupid design practice to attempt so I'm thinking it needs to be in the form of an array but can't seem to figure out how to do that with an Entry.
rowNum = 0
items = []
def tableGen(name):
global rowNum
entry = Entry(win).grid(row=rowNum, column=0)
label = Label(win, text=name).grid(row=rowNum, column=1)
self.items[rowNum] = [entry, label] # Problem Area 1
rowNum += 1
def generate(): # Print each items value
for item in items:
print (item.get()) # Problem Area 2
# Generates Entrys and labels from file
e = ET.parse('file.xml').getroot()
for atype in e.findall('things'):
tableGen(atype.get('name'))
generateBtn = Button(root, text="Generate", command=generate).pack()
generate()
root.mainloop()
I've simplifed the code to the minimal required to see what I'm trying to do. The problem seems to be either with where I put the items in a table or try and parse them (problem are 1 & 2). I'm very new to python and can't figure out how to do this. In it's current state the project fails with in tableGen self.items[rowNum] = [entry, label] Name Error: name 'self' is not defined.
Am I doing this wrong? Is there another way this can be done?
Solution
rowNum = 0
items = []
def tableGen(name):
global rowNum
entry = Entry(win)
entry.grid(row=rowNum, column=0)
label = Label(win, text=name)
label.grid(row=rowNum, column=1)
items.append([entry, label])
rowNum += 1
def generate(): # Print each items value
for item in items:
print('Entry:', item[0].get(), 'Label:', item[1].cget("text"))
# Generates Entrys and labels from file
e = ET.parse('file.xml').getroot()
for atype in e.findall('things'):
tableGen(atype.get('name'))
generateBtn = Button(root, text="Generate", command=generate).pack()
generate()
root.mainloop()
Use append() to add items to the end of a list:
def tableGen(name):
...
items.append([entry, label])
rowNum += 1
This will generate a list of lists, so you need to use an index to access the elements of each item:
def generate(): # Print each items value
for item in items:
print('Entry:', item[0].get(), 'Label:', item[1].get())
I'm trying to create a set of radiobuttons in Tkinter. One of the attributes I'd really like to have is the ability to tell which radiobutton was last entered. I tried to bind to each radiobutton. However when the event is triggered it returns the same value each time.
What am I doing wrong?
snippet:
i = 0
while i < 5 :
Frame = Tkinter.Frame(self.WS.SW.OptFrame, width=125, height=22, bd=1,
bg=self.WSbg)
Frame.grid(column=0, row=4 + i)
Frame.grid_propagate(0)
self.WS.SW.SearchFrame.append(Frame)
RB = Tkinter.Radiobutton(self.WS.SW.SearchFrame[i], value=i, #command=self.WSRB_UD,
variable=self.WS.RBvar, indicatoron=0, font=self.WSfo,
fg=self.WSfg, activeforeground=self.WSfg, bg=self.WSbg, activebackground=self.WSbg,
selectcolor=self.WSbg, bd=self.WSbw)
RB.grid()
RB.bind( "<Enter>", lambda event: self.WSRB_UD(event, i))
self.WS.SW.SearchRB.append(RB)
i = i + 1
self.QuickLinkList= []
self.WS_timer_count = 0
def WSRB_UD(self, event, opt):
m = self.WS.SW.SearchRB[opt-1].cget("value")
print m
Your lambda needs to be something like this:
lambda event, i=i: self.WSRB_UD(event, i))
This creates a local variable i inside the lambda that is bound to the value of i at the time the binding was created.