0

I have a list out_list = ["item1",item2","item3",....] which I am trying to add text_box and Entry for each item as the following:

enter image description here

But when I'm trying to get from the text box, text_box.get("1.0",'end-1c'), I am getting all of the list as one string.

Thanks for the help!

        for i in range(0,len(out_list)):
            text_box.window_create(text_box.index("end"), window=tk.Button(text_box, text="Copy Variable",command=buttonClick))
            text_box.window_create(text_box.index("end"), window=tk.Entry(text_box, text=str(out_list[i])))
            text_box.window_create(text_box.index("end"),text_box.insert(END, out_list[i]), window=text_box_value)
        text_box.insert(END,'\n')  # adds text to text box
4
  • text1_id = text_box.window_create(..) and now you can access first textbox using text1_id Commented Apr 26, 2021 at 12:15
  • or maybe you should first create entry_1 = tk.Entry(..) and keep it on list - to have access to this Entry, or to use command=lambda:buttonClick(entry_1) Commented Apr 26, 2021 at 12:19
  • or maybe you should use Frame to group elements Button, Entry, text and create own widget (with all needed functions for single row) and use this widget in for-loop Commented Apr 26, 2021 at 12:21
  • instead of for i in range(0,len(out_list)) you could learn to use for item in out_list: Commented Apr 26, 2021 at 12:21

1 Answer 1

1

You should first create Entry

entry = tk.Entry(text_box)
entry.insert("end", item)

and later you could use it in

command=lambda:button_click(entry))

but it is inside for-loop and lambda doesn't copy value from entry to code button_click(entry) so it keeps only reference to entry and this entry is changing in loop - and finally all lambda has reference to the same variable which has last value. You have to use extra variable to copy object.

command=lambda x=entry:button_click(x))

Minimal working code

import tkinter as tk   # PEP8: `import *` not preferred

# --- functions --- (PEP8: lower_case_names)

def button_click(entry):
    print('ENTRY:', entry.get())

# --- main ---

out_list = ["item1", "item2", "item3", ]  # PEP8: spaces after comma

root = tk.Tk()

text_box = tk.Text(root)
text_box.pack()

for item in out_list:
    print(item)
    
    entry = tk.Entry(text_box)
    entry.insert("end", item)
    
    button = tk.Button(text_box, text="Copy Variable", command=lambda x=entry:button_click(x))
    
    text_box.window_create(text_box.index("end"), window=button)
    text_box.window_create(text_box.index("end"), window=entry)
    #text_box.window_create(text_box.index("end"), text_box.insert('end', item), window=text_box_value)
    text_box.insert("end", item)
    text_box.insert("end", '\n')  # adds text to text box

root.mainloop()

EDIT:

You could also use Frame to build own widget with Button, Entry, Label and button_click and later use this widget.

It can be simpler to add or hide widget.

import tkinter as tk   # PEP8: `import *` not preferred

# --- classes --- (PEP8: CamelCaseNames) 

class MyWidget(tk.Frame):

    def __init__(self, master, text, *args, **kwargs):
        super().__init__(master, *args, **kwargs)
               
        self.button = tk.Button(self, text="Copy Variable", command=self.button_click)
        self.button.pack(side="left")
    
        self.entry = tk.Entry(self)
        self.entry.insert("end", text)
        self.entry.pack(side="left")
        
        self.label = tk.Label(self, text=text)
        self.label.pack(side="left")
        
    def button_click(self):
        print('ENTRY:', self.entry.get())
        #self.button["text"] = self.entry.get()
    
# --- functions --- (PEP8: lower_case_names)

def copy_all_variables():
    for widget in all_widgets:
        print(widget.entry.get())
        #widget.button_copy()

def add_widget():
    item = "item" + str(len(all_widgets)+1)
    widget = MyWidget(frame_widget, text=item)
    widget.pack(fill='x')
    all_widgets.append(widget)

def remove_widget():
    if all_widgets:
        all_widgets[-1].destroy()
        del all_widgets[-1]

# --- main ---

out_list = ["item1", "item2", "item3", ]  # PEP8: spaces after comma

root = tk.Tk()

# - version 1 -

tk.Label(root, text="Text Box + window_create()", bg="#8080ff").pack(fill='x', expand=True)

text_box = tk.Text(root)
text_box.pack()

all_widgets_1 = []

for item in out_list:
    widget = MyWidget(text_box, text=item)
    text_box.window_create(text_box.index("end"), window=widget)
    text_box.insert("end", '\n')  # adds text to text box
    all_widgets_1.append(widget)

# - version 2 -

tk.Label(root, text="Frame + pack()", bg="#8080ff").pack(fill='x', expand=True)

all_widgets = []

frame_widget = tk.Frame(root)
frame_widget.pack(fill='x')

for item in out_list:
    widget = MyWidget(frame_widget, text=item)
    widget.pack(fill='x')
    all_widgets.append(widget)
   
frame_buttons = tk.Frame(root)
frame_buttons.pack()   

button_copy = tk.Button(frame_buttons, text="Copy All Variables", command=copy_all_variables)
button_copy.pack(side="left")

button_add = tk.Button(frame_buttons, text="Add Widget", command=add_widget)
button_add.pack(side="left")

button_remove = tk.Button(frame_buttons, text="Remove Widget", command=remove_widget)
button_remove.pack(side="left")

# - 

root.mainloop()

enter image description here

And when you put Button and Entry directly to Text then you can write text between widgets.

enter image description here

Sign up to request clarification or add additional context in comments.

3 Comments

Hi furas, that's indeed what I meant, works perfect, I added a search to that list, but I am trying to "clean" the widgets once a updated list. I have tried the following: " for label in root.pack_slaves(): if label.pack_fo print(label) label.destroy()"
I don't know if I understand example code. if you mean to remove text from all labels then assing empty string - for widget in all_widgets: widget.label["text"] = "". If you mean to remove all widgets then for widget in all_widgets: widget.destroy() and all_widgets = [].
i noticed i inserted the wrong code - without buttons Add Widget and Remove Widget - but I put image with these buttons. Now code has these buttons.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.