我尝试过滤列表框中显示的内容,具体取决于当前所选的组合框项目。我不确定如何实现这一点,我甚至没有在网上找到一个简单明了的例子。有任何想法吗?我真的很感激一些帮助。
以下是代码摘录。
列表框:
class MyListBox(object):
def __init__(self, frame, listbox_header, listbox_list):
self.tree = ttk.Treeview(frame, columns=listbox_header, show='headings')
yScroll = ttk.Scrollbar(frame,orient='vertical', command=self.tree.yview)
yScroll.pack(side=RIGHT, fill=Y)
self.tree.config(yscrollcommand=yScroll.set)
self.tree.pack(side=LEFT, fill=Y, expand=TRUE)
for col in listbox_header:
self.tree.heading(col, text=col.title(),command=lambda c=col: sortby(self.tree, c, 0))
self.update_rows(listbox_list)
self.tree.bind('<Double-1>', self.OnDoubleClick)
def update_rows(self, listbox_list):
items = self.tree.get_children()
for item in items:
self.tree.delete(item)
for item in listbox_list:
self.tree.insert('', 'end', values=item)
def OnDoubleClick(self, event):
item = self.tree.selection()[0]
self.Info(self.tree.item(item, 'values'))
#Single student information window. Display all courses in student listbox
def Info(self, selected):
info = Toplevel()
info.title('Student Information: %s - %s - %s' % (selected[0], selected[1], selected[2]))
info.geometry('%dx%d+%d+%d' % (WIDTH, HEIGHT, 50, 50))
student = session.query(Student).filter_by(id=selected[0]).first()
#Single student header label info
Label(info, text='Total All Attempts: %s' % student.gpa).pack()
Label(info, text='Total Best Attempts: %s' % student.best_gpa).pack()
Label(info, text='Spec GPAs: %s' % student.rules_gpas).pack()
Label(info, text='Spec GPAs Needed: %s' % student.rules_gpas_needed).pack()
#Single Student course info list
Label(info, text='\nAll Courses:').pack()
current = session.query(Course.sid, Course.term, Course.subject, Course.number,
Course.title, Course.grade, Course.grade_val, Course.hours).\
order_by(Course.term.desc(), Course.subject, Course.number, Course.grade_val.desc()).filter_by(sid=selected[0])
course_header = ['ID', 'term', 'subject', 'number', 'title', 'grade', 'grade_val', 'hours']
#setup listbox and scroll bars
tree = ttk.Treeview(info, columns=course_header, show='headings')
yScroll = ttk.Scrollbar(info, orient='vertical', command=tree.yview)
yScroll.pack(side=RIGHT, fill=Y)
tree.config(yscrollcommand=yScroll.set)
tree.pack(side=LEFT, fill=BOTH, expand=TRUE)
for col in course_header:
tree.heading(col, text=col.title(), command=lambda c=col: sortby(tree, c, 0))
tree.column(col, width=50, anchor='center')
tree.column('title', width=150, anchor='w')
for item in current:
tree.insert('', 'end', values=item)
这是组合框:
# This creates the drop menu (combobox)
Label(top, text='View Concentration:').pack(side=LEFT)
box_value = StringVar()
box = ttk.Combobox(top, textvariable=box_value, state='readonly')
titles = []
titles.append('All')
for rule in rules:
titles.append((rule.title))
box['values'] = titles
box.current(0)
box.pack(side=LEFT)
答案 0 :(得分:1)
根据我的理解,每次组合框更改时,您要做的是清除并重新填充列表框。令人惊讶的是,它并不太难。
这是我的示例应用。它利用root.after来递归检查组合框是否已更改。请注意,可能有一种方法可以将更新功能绑定到StringVar.set
命令,我只是不知道它是什么。您也可以使用StringVar进行子类化,但无论如何:
# Import
import Tkinter
import ttk
# Class
class App:
# Init
def __init__(self):
self.options = ["All", "Odd", "Even"] # Combobox elements
self.values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] # Treeview elements
self.last_filter_mode = "" # Combobox change detector
self.create()
# Build GUI
def create(self):
self.root = Tkinter.Tk() # Can be substituted for Toplevel
self.root.title("Filtered Listbox")
self.frame = Tkinter.Frame(self.root)
# I like to use pack because I like the aesthetic feel
# pady is 5 so that the widgets in the frame are spaced evenly
self.frame.pack(fill="both", padx=10, pady=5)
self.filter_mode = Tkinter.StringVar(); # Combobox StringVar
# Set it to the initial value of combobox
# Also consider using self.options[0] for uniformity
self.filter_mode.set("All")
self.combobox = ttk.Combobox(
self.frame, textvariable=self.filter_mode, state="readonly",
values=self.options)
self.combobox.pack(fill="x", pady=5)
# So that the scroll bar can be packed nicely
self.treeview_frame = Tkinter.Frame(self.frame)
self.treeview_frame.pack(fill="x", pady=5)
column_headings = ["A", "B", "C"] # These are just examples
self.treeview = ttk.Treeview(
self.treeview_frame, columns=column_headings, show="headings")
self.treeview.pack(fill="y", side="left")
self.treeview_scroll = ttk.Scrollbar(
self.treeview_frame, orient="vertical", command=self.treeview.yview)
self.treeview_scroll.pack(fill="y", side="right")
self.treeview.config(yscrollcommand=self.treeview_scroll.set)
# Recursize update function called with root.after
def update(self):
filter_mode = self.filter_mode.get()
# Check for change in the filter_mode
if filter_mode != self.last_filter_mode:
items = self.treeview.get_children()
for item in items:
self.treeview.delete(item) # Clear the treeview
# Combobox options
if filter_mode == "All":
for element in self.values:
self.treeview.insert("", "end", values=(element))
if filter_mode == "Odd":
for element in filter(
lambda x: True if x % 2 != 0 else False, self.values):
self.treeview.insert("", "end", values=(element))
if filter_mode == "Even":
for element in filter(
lambda x: True if x % 2 == 0 else False, self.values):
self.treeview.insert("", "end", values=(element))
self.last_filter_mode = filter_mode # Update current filter mode
self.root.after(100, self.update) # Call this function again
def main(self):
self.update() # Start the recursive update function
self.root.mainloop() # Start the app
a = App()
a.main()
我知道它有点复杂,将它集成到您当前的代码中可能很困难,但如果您有任何问题可以随意提问!希望这有帮助!