Warm tip: This article is reproduced from serverfault.com, please click

Problem with getting Entry and checkbutton values Tkinter

发布于 2020-11-27 22:35:47

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
Questioner
dick taylor
Viewed
11
Bryan Oakley 2020-11-28 08:03:31

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}")