0

I have a tkinter window that am creating labels and entry widgets based on a list made by a database query.

I need to use the values entered in the entry widgets to create a new list to put into another database.

The list from the database has a variable count. I use a loop to create the labels and entry widgets but can't work out how to name the entry widgets to be able to put the entries into a usable list. Ideally it will have the e.get from the original query and the list tied to each of the entries.

Heres what i have so far.

    #Create frame for Size inputs and labels
        sizes_frame = tk.Frame(p,bg='yellow')
        sizes_frame.grid(row=2,column=1)
        connection = sqlite3.connect('productdata.db')
        pro = connection.cursor()
        pro.execute("SELECT Size FROM Products WHERE ColourCode = ?", (e.get(),))
        connection.commit()
        Sizes = pro.fetchall()
            
        keys = Sizes
        otherkeys = Sizes
        count = 0
        othercount = 0
        labels=[]
        otherlabels=[]
    
        for j,l in enumerate(labels):
            l.config(text=str(keys[j])+str(j))
        for key in keys:
            
            labels.append(Label(sizes_frame,text=key,font=('Helvatical bold',10)))
            if count <10:
                labels[count].grid(row = count, column = 1, padx=5, pady= 5)
                count+=1
            else:
                labels[count].grid(row = count-10, column = 3, padx=5, pady= 5)
                count += 1
    
        for j,l in enumerate(otherlabels):
            l.config(text=str(otherkeys[j])+str(j)) 
        for otherkey in otherkeys:
            otherlabels.append(Entry(sizes_frame,width= 6))
            if othercount<10:
                otherlabels[othercount].grid(row = othercount, column = 2, padx=5, pady= 5)
                othercount += 1
            else:
                otherlabels[othercount].grid(row = othercount-10, column = 4, padx=5, pady= 5)
                othercount += 1
  • if you keep Entry on lis then later use `for`-loop to get values `otherlabels[index].get()`. But maybe it would be simpler to use dictionary instead of list - `all_entries[field_name] = ... ` and later `all_entries[field_name].get()` – furas Apr 06 '22 at 10:54
  • if you may have more `e.get()` then maybe you should create nested dictionaries - `all_entries[e.get()][field_name] = ...` and later `all_entries[e.get()][field_name].get()` – furas Apr 06 '22 at 11:00
  • you should use more readable variables - `number` instead of `j`, `label` instead `l`, `entries` instead of `otherlabels`, etc. See more in [PEP 8 -- Style Guide for Python Code](https://www.python.org/dev/peps/pep-0008/) – furas Apr 06 '22 at 11:05
  • I don't understand why you use `for j,l in enumerate(labels):` if you have empty list `labels = []`. The same with `otherlabels = []`. – furas Apr 06 '22 at 11:07
  • you could create labels and entries in one `for`-loop and you could use `enumerate()` instead of `count` and `anothercount` - and there is no need to assign `Sizes` to `keys` and `otherkeys` - you could use directly `for number, size in enumerate(sizes):`. And this way you would have less variables and code could be more readable. – furas Apr 06 '22 at 11:10

1 Answers1

0

I'm not sure if I understand problem but maybe you should use dictionary with nested list instead of list

all_labels  = { e.get(): [] }  # list inside dictionary
all_entries = { e.get(): [] }  # list inside dictionary

and later append widgets

all_labels[e.get()].append(label)
all_entries[e.get()].append(entry)

And later you can get all values using for loop and e.get()

for entry in all_entries[e.get()]:
    print(entry.get())

Eventually you can use nested dictionares

all_labels  = { e.get(): {} }  # dictionary inside dictionary
all_entries = { e.get(): {} }  # dictionary inside dictionary

and later append widgets

all_labels[e.get()][size] = label
all_entries[e.get()][size] = entry

And later you can get all values using for loop and e.get() and .items()

for size, entry in all_entries[e.get()].items():
    print(size, entry.get())

Minimal example with other changes to make code more readable.

Because words entry,entries and label,labels and size,sizes are very similar (and it can make problems) so I use prefix `all_

sizes_frame = tk.Frame(p, bg='yellow')
sizes_frame.grid(row=2, column=1)

connection = sqlite3.connect('productdata.db')
pro = connection.cursor()
pro.execute("SELECT Size FROM Products WHERE ColourCode = ?", (e.get(),))
connection.commit()

all_sizes = pro.fetchall()
    
all_labels  = { e.get(): {} }
all_entries = { e.get(): {} }

for number, size in enumerate(all_sizes):
    label = tk.Label(sizes_frame, text=size, font=('Helvatical bold',10))
    entry = tk.Entry(sizes_frame, width=6)
    
    if number < 10:
        label.grid(row=number, column=1, padx=5, pady=5)
        entry.grid(row=number, column=2, padx=5, pady=5)
    else:
        label.grid(row=number-10, column=3, padx=5, pady=5)
        entry.grid(row=number-10, column=4, padx=5, pady=5)
        
    all_labels[e.get()][size] = label)
    all_entries[e.get()][size] = entry


# --- in some function ---

for size, entry in all_entries[e.get()].items():
    print(size, entry.get())
    # ... add `size` and `entry.get()` to database

furas
  • 134,197
  • 12
  • 106
  • 148
  • Thank you very much for your detailed explainantions. Your final code works bar 1 extra ) after label. next is to work out hwo to manipulate the result to input back into database. Thanks again – John Glanville Apr 06 '22 at 12:00
  • I don't know what values you get in `entry` but first you need place in database for these values - and I don't know where you want to keep it. And later in `for`-loop you get size and `entry.get()` and run `INSERT` or `UPDATE`. if you create query with `?` for both values then you could first get all pairs `(size, entry.get())` and later use `executemany(...)` to execute query on all pairs at once (without `for`-loop) – furas Apr 06 '22 at 12:16
  • Its for a clothing sheet order. Product Code, Colour, Size, Quantity. – John Glanville Apr 07 '22 at 07:53
  • Light Blue GD72 ('S',) 1
    Light Blue GD72 ('M',) 2
    Light Blue GD72 ('L',) 3
    Light Blue GD72 ('XL',) 4
    Light Blue GD72 ('XXL',) 5
    GRRRRRR why won't the line break work in comments
    – John Glanville Apr 07 '22 at 07:53
  • `def addtoorder(): global all_entries , entry, e for size, entry in all_entries[e.get()].items(): print(e.get() , size , entry.get())` – John Glanville Apr 07 '22 at 07:58
  • comments don't have functions to format code. You should put all information in question - it will be more readable. but if you have new problem then you should rather create new new question on new page. – furas Apr 07 '22 at 08:31
  • 1
    Thanks, I'm ok for now. will write some code for the next step and post new question if i have any issues. Thank you again for your help. Just wanted to share with you what i was doing and how i was using your changes. – John Glanville Apr 07 '22 at 08:35