【问题标题】:Create text_box with Entry for a list - tkinter Python为列表创建带有条目的 text_box - tkinter Python
【发布时间】:2021-07-19 15:58:59
【问题描述】:

我有一个列表 out_list = ["item1",item2","item3",....],我正在尝试为每个项目添加 text_box 和 Entry,如下所示:

但是当我尝试从文本框text_box.get("1.0",'end-1c') 中获取时,我将所有列表都作为一个字符串获取。

感谢您的帮助!

        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

【问题讨论】:

  • text1_id = text_box.window_create(..) 现在您可以使用text1_id访问第一个文本框
  • 或者也许您应该首先创建entry_1 = tk.Entry(..) 并将其保留在列表中 - 以访问此条目,或使用command=lambda:buttonClick(entry_1)
  • 或者您应该使用Frame 对元素ButtonEntrytext 进行分组并创建自己的小部件(具有单行所需的所有功能)并在@987654335 中使用此小部件@-循环
  • 你可以学习使用for i in range(0,len(out_list))而不是for item in out_list:

标签: python user-interface tkinter textbox tkinter-entry


【解决方案1】:

你应该先创建Entry

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

以后你可以用它

command=lambda:button_click(entry))

但它在for-loop 内部,并且lambda 不会将值从entry 复制到代码button_click(entry),因此它只保留对entry 的引用,并且这个entry 在循环中发生变化 - 并且最后,所有 lambda 都引用了具有最后一个值的相同变量。您必须使用额外的变量来复制对象。

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

最少的工作代码

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()

编辑:

您还可以使用Frame 来构建自己的小部件,其中包含ButtonEntryLabelbutton_click,然后再使用这个小部件。

添加或隐藏小部件会更简单。

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()

当您将ButtonEntry 直接放入Text 时,您可以在小部件之间写入文本。

【讨论】:

  • 嗨 furas,这确实是我的意思,效果很好,我在该列表中添加了一个搜索,但我正在尝试在更新列表后“清理”小部件。我尝试了以下方法:“ for label in root.pack_slaves(): if label.pack_fo print(label) label.destroy()”
  • 我不知道我是否理解示例代码。如果您的意思是从所有标签中删除文本,则使用空字符串 - for widget in all_widgets: widget.label["text"] = ""。如果您要删除所有小部件,那么 for widget in all_widgets: widget.destroy()all_widgets = []
  • 我注意到我插入了错误的代码 - 没有按钮 Add WidgetRemove Widget - 但我用这些按钮放置了图像。现在代码有了这些按钮。
【解决方案2】:

我已将滚动添加到根框架,但无法使其向上/向下滚动

root = tk.Tk()
scrollbar = tk.Scrollbar(root)
scrollbar.pack( side = RIGHT,fill = Y )

【讨论】:

    猜你喜欢
    • 2013-07-30
    • 1970-01-01
    • 2011-11-22
    • 1970-01-01
    • 2017-10-19
    • 2013-11-07
    • 1970-01-01
    • 2022-01-04
    • 1970-01-01
    相关资源
    最近更新 更多