簡體   English   中英

Python Tkinter Treeview 過濾器

[英]Python Tkinter Treeview Filters

是否可以過濾 treeview 小部件中的列,例如 excel。 我在堆棧溢出時發現了這段代碼(由 oskros),它完成了這項任務,但是如果我想用多個值過濾單個列怎么辦。 此代碼僅允許過濾一個值。

from tkinter import *
from tkinter import ttk

inp = [{'Currency': 'EUR', 'Volume': '100', 'Country': 'SE'},
       {'Currency': 'GBR', 'Volume': '200', 'Country': 'SE'},
       {'Currency': 'CAD', 'Volume': '300', 'Country': 'SE'},
       {'Currency': 'EUR', 'Volume': '400', 'Country': 'SE'},
       {'Currency': 'EUR', 'Volume': '100', 'Country': 'DK'},
       {'Currency': 'GBR', 'Volume': '200', 'Country': 'DK'},
       {'Currency': 'CAD', 'Volume': '300', 'Country': 'DK'},
       {'Currency': 'EUR', 'Volume': '400', 'Country': 'DK'},
       ]


class Application(Tk):
    def __init__(self):
        Tk.__init__(self)
        self.title("Volume")

        combofr = Frame(self)
        combofr.pack(expand=True, fill=X)
        self.tree = ttk.Treeview(self, show='headings')
        columns = list(inp[0].keys())

        self.filters = []

        for col in columns:
            name = 'combo_' + col
            self.filters.append(name)
            setattr(self, name, ttk.Combobox(combofr, values=[
                    ''] + sorted(set(x[col] for x in inp)), state="readonly"))
            getattr(self, name).pack(side=LEFT, expand=True, fill=X)
            getattr(self, name).bind(
                '<<ComboboxSelected>>', self.select_from_filters)

        self.tree["columns"] = columns
        self.tree.pack(expand=TRUE, fill=BOTH)

        for i in columns:
            self.tree.column(i, anchor="w")
            self.tree.heading(i, text=i, anchor="w")

        for i, row in enumerate(inp):
            self.tree.insert("", "end", text=i, values=list(row.values()))

    def select_from_filters(self, event=None):
        self.tree.delete(*self.tree.get_children())

        def all_filter(x): return all(x[f.split('_')[-1]] == getattr(
            self, f).get() or getattr(self, f).get() == '' for f in self.filters)
        for row in inp:
            if all_filter(row):
                self.tree.insert("", "end", values=list(row.values()))


root = Application()
root.mainloop()

我想出了這個版本,但是您必須輸入值,如果有分配的記錄,您需要向下滾動以查找需要過濾的所有記錄。

from tkinter import *
from tkinter import ttk

inp = [{'Currency': 'EUR', 'Volume': '100', 'Country': 'SE'},
       {'Currency': 'GBR', 'Volume': '200', 'Country': 'SE'},
       {'Currency': 'CAD', 'Volume': '300', 'Country': 'SE'},
       {'Currency': 'EUR', 'Volume': '400', 'Country': 'SE'},
       {'Currency': 'EUR', 'Volume': '100', 'Country': 'DK'},
       {'Currency': 'GBR', 'Volume': '200', 'Country': 'DK'},
       {'Currency': 'CAD', 'Volume': '300', 'Country': 'DK'},
       {'Currency': 'EUR', 'Volume': '400', 'Country': 'DK'},
       ]


def trim(list):
    return list.replace(" ", "")


class Application(Tk):
    def __init__(self):
        Tk.__init__(self)
        self.title("Volume")

        combofr = Frame(self)
        combofr.pack(expand=True, fill=X)
        self.tree = ttk.Treeview(self, show='headings')
        columns = list(inp[0].keys())

        self.filters = []

        for col in columns:
            name = 'combo_' + col
            self.filters.append(name)
            setattr(self, name, ttk.Entry(combofr))
            getattr(self, name).pack(side=LEFT, expand=True, fill=X)
            getattr(self, name).bind(
                '<Return>', self.select_from_filters)

        self.tree["columns"] = columns
        self.tree.pack(expand=TRUE, fill=BOTH)

        for i in columns:
            self.tree.column(i, anchor="w")
            self.tree.heading(i, text=i, anchor="w")

        for i, row in enumerate(inp):
            self.tree.insert("", "end", text=i, values=list(row.values()))

    def select_from_filters(self, event=None):
        self.tree.delete(*self.tree.get_children())

        filters = [list(map(trim, getattr(self, f).get().split(",")))
                   for f in self.filters]

        print(filters)

        def all_filter(x): return all(x[f.split('_')[-1]] in filters[i] or getattr(
            self, f).get() == '' for i, f in enumerate(self.filters))
        for row in inp:
            if all_filter(row):
                self.tree.insert("", "end", values=list(row.values()))


root = Application()
root.mainloop()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM