Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用组合框进行列表框筛选_Python_Python 2.7_Combobox_Listbox_Tkinter - Fatal编程技术网

Python 使用组合框进行列表框筛选

Python 使用组合框进行列表框筛选,python,python-2.7,combobox,listbox,tkinter,Python,Python 2.7,Combobox,Listbox,Tkinter,我正试图根据组合框中当前选定的项目筛选列表框中显示的内容。我不知道如何才能做到这一点,我甚至没有在网上找到一个简单的例子。有什么想法吗?我非常感谢你的帮助 下面是代码摘录 列表框: class MyListBox(object): def __init__(self, frame, listbox_header, listbox_list): self.tree = ttk.Treeview(frame, columns=listbox_header, show='headin

我正试图根据组合框中当前选定的项目筛选列表框中显示的内容。我不知道如何才能做到这一点,我甚至没有在网上找到一个简单的例子。有什么想法吗?我非常感谢你的帮助

下面是代码摘录

列表框:

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)

据我所知,您试图做的是在组合框每次更改时清除并重新填充列表框。令人惊讶的是,这并不太难

下面是我的示例应用程序。它利用root.after递归检查组合框是否已更改。请注意,可能有一种方法可以将update函数绑定到
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()
我知道这有点复杂,将其集成到当前代码中可能很困难,但如果您有任何问题,请随时提问!希望这有帮助

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