使Tkinter过滤列表框更具动态性

时间:2017-04-14 01:01:51

标签: python tkinter

This is the Tkinter window when calling addFilterList(list) 我这样调用了这个函数:

tkWindow = TkWindow()
tkWindow.addFilterList(['A','B','C','D','E','F','G','H','I','J','K','L'])
tkwindow.runwindow()

我有这个TKinker课程。我被困在了使这更有活力的方法上。首先,滚动条,按钮和列表框被硬编码为位于窗口中的特定位置。有没有办法获得这种格式,无论它出现在Tkinter窗口的哪个位置。例如,如果我在顶部有一堆按钮,我希望此功能以这种格式显示,而不必返回代码并更改其行或列位置。

第二:我设置它的方式,每个TkWindow只能有一个addFilterList,因为返回值。有人可以指出我如何更改代码的正确方向,以便我可以在一个Tkinter窗口中返回多个Listbox的值。

class TkWindow(object):

def __init__(self):
    self.top = tk.Tk()

def addFilterList(self, list_box):
    self.list_box = list_box

    self.value = []

    self.text_field = tk.StringVar()

    self.entry = tk.Entry(self.top, textvariable=self.text_field, width=60)
    self.listbox = tk.Listbox(self.top, width=40, selectmode=tk.MULTIPLE)
    self.entry.grid()
    self.listbox.grid(row=7)

    self.text_field.trace("w", lambda name, index, mode: self.update_list())


    self.button_show = tk.Button(self.top, text="Select",
                                 command=self.selected_item)
    self.button_clear = tk.Button(self.top, text="Clear",
                                  command=self.clear)
    self.scrollbar = tk.Scrollbar(self.top)
    self.show_list = tk.Listbox(self.top, width=60, height=4)
    self.scrollbar.grid(row=7, sticky=tk.N + tk.S + tk.E, padx=(10, 50))
    self.button_show.grid(row=8, padx=(10, 300))
    self.button_clear.grid(row=8, sticky=tk.E, padx=(10, 100))
    self.show_list.grid()

    # Add scrollbar
    self.listbox.config(yscrollcommand=self.scrollbar.set)
    self.scrollbar.config(command=self.listbox.yview)
    self.update_list()

def update_list(self):
    # Used in addFilterList()
    search_term = self.text_field.get()
    self.listbox.delete(0, tk.END)
    for item in self.list_box:
        if search_term.lower() in item.lower():
            self.listbox.insert(tk.END, item)

def selected_list(self):
    # Used in addFilterList()
    self.show_list.delete(0, tk.END)
    for item in self.value:
        self.show_list.insert(tk.END, item)
    self.selected = self.listbox.selection_clear(0, tk.END)

def selected_item(self):
    # Used in addFilterList()
    self.selected = self.listbox.curselection()
    for i in self.selected:
        self.value.append(self.listbox.get(i))
    self.selected_list()

def clear(self):
    # Used in addFilterList()
    self.value = []
    self.show_list.delete(0, tk.END)

def return_value(self):
    return self.value

def runWindow(self):
    self.top.mainloop()

1 个答案:

答案 0 :(得分:0)

我不确定我理解你的问题,但我会尝试提供一些建议。我认为你试图在函数addFilterList中做太多事情。因此,您的代码很难阅读和修改。你有三件不同的事情要做:

  1. 初始化小部件
  2. 布置小部件
  3. 使用值填充小部件
  4. 我通常在构造函数中执行#1。所以你的构造函数将是大纲:

    def __init__(self):
       self.top = tk.Tk()
       self.entry = tk.Entry(...)
       self.listbox = tk.ListBox(...)
    

    然后我在一个单独的函数中进行布局,称之为doLayout()

    def doLayout(self):
        self.entry.grid(...)
        self.listbox.grid(...)
    

    现在,只有将项目列表添加到列表框中,您的函数addFilterList才会受到关注。您可以在不更改此功能的情况下更改布局。您可以在不更改此功能的情况下向窗口添加其他小部件。

    如果您想拥有多个FilterList,可以考虑创建tk.Listbox的子类。这里的函数将设置列表内容,清除列表内容,处理列表选择事件等。然后,如果您决定要两个列表而不是一个列表,则可以实例化该类的另一个实例并将其添加到窗口中。