让用户能够查看字符串列表并在 tkinter window 中编辑这些字符串的最佳方式是什么?

What would be the best way for a user to be able to view a list of strings and edit those strings in a tkinter window?

这个标题可能让我的目标听起来有点混乱,因为我不确定如何用最好的方式表达它,但我想添加编辑字符串列表的功能,允许用户编辑它们, 然后将它们保存到我当前正在处理的程序中。一个简单的方法是创建一个 label 和一个对应的 entry 并将变量的值设置为 entry.get()。如:

row=0
for line in build: # build is a list of strings
    Label(build_window,text=line).grid(row=row,column=0,sticky=W) 
    # build_window is a Toplevel of 'main_screen'
    Entry(build_window).grid(row=row,column=1,sticky=W) 
    # I know I'd need to save the entry as a variable or some other way in order to access
    # the value but I left it like this for demonstration
    row+=1

这将在同一行创建一个标签和一个条目,然后将保存 entry.get() 的值。但问题是 build 包含 50 多行字符串,此设置需要非常大量的 space 才能使用。您可以使用 Listbox()Scrollbar() 来达到这种效果吗? (问这就是我之前在我的程序中列出它们的方式)我试过索引一个 Listbox() object 就像你会一个普通列表 (ListboxObject[1]) 但它只是 returns 一个错误说它需要一个字符串,而不是一个整数。

如 acw1668 所建议,您可以使用 ListboxEntry 的组合。每次列表框的选择发生变化(<<ListboxSelect>> 事件)时,条目的内容都设置为当前选择的字符串。然后用户可以编辑条目中的字符串并单击编辑按钮以验证更改。

import tkinter as tk

def on_listbox_select(event):
    index = listbox.curselection()  # get index of selected line in listbox
    entry.delete(0, 'end')          # clear the entry
    if not index:
        return
    entry.insert(0, listbox.get(index))  # put the selected string in the entry

def edit():
    index = listbox.curselection()  # get index of selected line in listbox
    if not index:  
        return  # no selected line, do nothing
    # replace lisbox line with new string
    listbox.delete(index)  
    listbox.insert(index, entry.get())
    listbox.see(index)
    entry.delete(0, 'end')  # clear the entry

root = tk.Tk()
root.rowconfigure(0, weight=1)
build = ['string %i' % i for i in range(50)]
listbox = tk.Listbox(root, exportselection=False)
listbox.grid(row=0, column=0, sticky='ewsn')
# scrollbar
sb = tk.Scrollbar(root, orient='vertical', command=listbox.yview)
sb.grid(row=0, column=1, sticky='ns')
listbox.configure(yscrollcommand=sb.set)
# put content in listbox
for line in build:
    listbox.insert('end', line)
# entry to edit the strings
entry = tk.Entry(root)
entry.grid(row=1, column=0, sticky='ew')
# validate button
tk.Button(root, text='Edit', command=edit).grid(row=2)

listbox.bind('<<ListboxSelect>>', on_listbox_select)
root.mainloop()

另一种解决方案是使用 Text() 对象,由于我没有使用它们,我忘记了它。

def edit_current_build(self,build_window,build):
    perkList=tk.Text(build_window,width=59)
    perkList.grid()

    perkScrollbar=tk.Scrollbar(build_window,orient='vertical',command=perkList.yview)
    perkScrollbar.grid(row=0,column=1,sticky='ns')
    perkList.configure(yscrollcommand=perkScrollbar.set)

    for line in build:
        perkList.insert(END,line)

        tk.Button(build_window,text='Save',command=lambda:self.save(build_window,build,perkList)).grid(sticky=W)

def save(self,build_window,build,perkList):
    currentBuild=[]
    for line in perkList.get('1.0','end-1c').split('\n'): # seperates lines but '\n' is added later as I still want the newlines
        line+='\n'
        currentBuild.append(line)