I am writing a program that creates a frame with grid Geometry Management. In that frame I create 5 rows and 7 columns with a loop. In each row, I have 5 columns of entrys and two columns of checkbuttons. Each entry and checkbox is assigned to a variable and that variable is stored in a dictionary using the (row,column) from the grid geometry management as the key.
widgets = {}
widgetsValue = {}
for i in range(rows): #Rows
for j in range(columns): #Columns
if j == 2 or j == 3: #column 2 and 3 is a checkbox
test = IntVar()
c = Checkbutton(inputFrame, bd=1, variable=test)
c.grid(row=2+i, column=j)
widgets[(i, j)] = c
widgetsValue[(i,j)] = test
else: # everything other than column 2 and 3 is a entry
test1 = StringVar()
e = Entry(inputFrame, text="", textvariable=test1)
e.grid(row=2+i, column=j)
widgets[(i, j)] = e
widgetsValue[(i,j)] = test1
Now I am having trouble creating a button that once it has been clicked it will update a label with the values of the each row in the form of "row 1: "entryvalue, entryvalue, checkbuttonvalue, checkbuttonvalue, entryvalue, entryvalue", row 2: " and so on.
Here is my idea.
def submit():
global mystr
for i in range(rows): #Rows
mystr += "row[" + i + "]: "
for j in range(columns):
if (i,j) in widgets:
if widgets[(i,j)].winfo_class() == Entry:
if len(widgets[(i,j)].get()) != 0 :
mystr += widgets[(i,j)].get() + ", "
if widgets[(i,j)].winfo_class() == Checkbutton:
mystr += str(widgetsValue[(i,j)]) + ", "
myArr.append(mystr)
for x in myArr:
mystr += x
hiddenLabel['text'] = mystr # update hiddenlabel with mystr
enter code here
Since you're using an IntVar
for every value, you just need to iterate over every row. For any row and column you can use widgetsValue[(i, j)]
.
For example, here's a simple way to create a list of values for row 0:
values = [
widgetsValue[(0,0)].get(),
widgetsValue[(0,1)].get(),
widgetsValue[(0,2)].get(),
widgetsValue[(0,3)].get(),
widgetsValue[(0,4)].get(),
widgetsValue[(0,5)].get(),
widgetsValue[(0,6)].get(),
]
Python has something called a list comprehension, which makes it easy to condense that down into a single line:
values = [widgetsValue[(0,j)].get()) for j in range(columns)]
To convert that to a string of comma-separated values, we can use another list comprehension to convert that to a list of strings, and from that we can join the values with commas:
values = [str(value) for value in values]
values = ", ".join(values)
We can easily do all that in a loop so that we can get each row separately. Notice that the code uses i
instead of a hard-coded zero like in the previous examples:
for i in range(rows):
values = [widgetsValue[(i,j)].get() for j in range(columns)]
values = [str(value) for value in values]
values = ", ".join(values)
You wanted the row number, so we can use a formatted string literal (or fstring) with a print
statement to print the values to the terminal:
print(f"row {i}: {values}")
Putting it all together, and combining the first two list comprehensions into one, we end up with this:
for i in range(rows):
values = [str(widgetsValue[(i,j)].get()) for j in range(columns)]
values = ", ".join(values)
print(f"row {i}: {values}")
this works but im curious is there away to use widgets.get instead of widgetsvalue.get?
@dicktaylor: yes, you can use
widgets.get
. The solution will be more complicated since checkbuttons don't have aget
method. Or, just create a single list that has entry widgets and then theIntVar
for the checkbuttons. As long as every item in the list has aget
method, this exact solution will work.