简短的回答
我创建了一个使用它的示例项目:
import tkinter as tk
import tkinter.ttk as ttk
import sys
from numpy import select
import pandas
# https://gist.githubusercontent.com/netj/8836201/raw/6f9306ad21398ea43cba4f7d537619d0e07d5ae3/iris.csv
df = pandas.read_csv('./booklist.csv')
df.columns = df.columns.str.replace('.', '', regex=False)
df.columns = df.columns.str.replace(' ', '_', regex=False)
df.head()
class main_window:
def __init__(self, root):
self.root = root
root.title("Treeview Search Example")
# Create DataFrame for this window
self.build_df = df.copy()
self.checkout_ids = []
# INITIALIZE TREEVIEW + SCROLLVIEW
self.tree = ttk.Treeview(root, columns=list(df.columns.values), show='headings')
self.tree.grid(row=1, column=0, sticky='nsew')
# https://stackoverflow.com/a/41880534/5210078
vsb = ttk.Scrollbar(root, orient="vertical", command=self.tree.yview)
vsb.grid(row=1, column=1, sticky='ns')
self.tree.configure(yscrollcommand=vsb.set)
for column in self.tree['column']:
self.tree.heading(column,text=column)
df_rows = df.to_numpy().tolist()
for row in df_rows:
if row[4] != 0:
self.tree.insert("","end",values=row)
# ADD SEARCH BOXES
search_frame = tk.Frame(root)
search_frame.grid(row=0, column=0, columnspan=2, sticky='nsew')
tk.Label(search_frame, text="TITLE:").grid(row=0, column=0)
tk.Label(search_frame, text="AUTHOR:").grid(row=0, column=2)
tk.Label(search_frame, text="IDENTIFICATION NO:").grid(row=0, column=4)
tk.Label(search_frame, text="SUBJECT CATEGORY:").grid(row=0, column=6)
# Add Search boxes
self.title_ent = tk.Entry(search_frame)
self.title_ent.grid(row=0, column=1)
self.author_ent = tk.Entry(search_frame)
self.author_ent.grid(row=0, column=3)
self.identifaction_ent = tk.Entry(search_frame)
self.identifaction_ent.grid(row=0, column=5)
self.category_ent = tk.Entry(search_frame)
self.category_ent.grid(row=0, column=7)
tk.Button(search_frame, text="Search", command=self.search).grid(row=0, column=10)
tk.Button(search_frame, text="Reseve", command=self.reserve).grid(row=0, column=11)
def search(self):
# https://stackoverflow.com/a/27068344/5210078
self.tree.delete(*self.tree.get_children())
self.build_df = df.copy()
# https://stackoverflow.com/a/56157729/5210078
entries = [
self.title_ent,
self.author_ent,
self.identifaction_ent,
self.category_ent
]
if entries[0].get():
self.build_df = self.build_df[self.build_df.TITLE.str.contains(entries[0].get())]
if entries[1].get():
self.build_df = self.build_df[self.build_df.AUTHOR.str.contains(entries[1].get())]
if entries[2].get():
self.build_df = self.build_df[self.build_df.SUBJECT_CATEGORY.str.contains(entries[2].get())]
if entries[3].get():
self.build_df = self.build_df[self.build_df.PUBLICATION_DATE == (entries[3].get())]
df_rows = self.build_df.to_numpy().tolist()
for row in df_rows:
print(row)
if row[4] != 0:
self.tree.insert("","end",values=row)
def reserve(self):
selected = self.tree.item(self.tree.focus())
if selected['values']:
# get the id
book_id = selected['values'][3]
book_id_val = df.loc[df['IDENTIFICATION_NO'] == book_id, 'BOOK_ITEM'].to_numpy().tolist()[0]
if book_id_val < 1:
return 0
else:
self.checkout_ids.append(book_id)
df.loc[df['IDENTIFICATION_NO'] == book_id, 'BOOK_ITEM'] = book_id_val - 1
self.search()
if __name__ == '__main__':
main = tk.Tk()
main_window(main)
main.mainloop()
sys.exit()
booklist.csv 如下所示:
TITLE,AUTHOR,PUBLICATION DATE,IDENTIFICATION NO.,BOOK ITEM,SUBJECT CATEGORY
Book 1,Author 1,1923,001/geo003/1993,4,Awesome
Book 2,Author 2,1924,001/geo003/1994,5,Awesome
Book 3,Author 3,1925,001/geo003/1995,6,Awesome
Book 4,Author 4,1926,001/geo003/1996,7,Awesome
Book 5,Author 5,1927,001/geo003/1997,8,Awesome
Book 6,Author 6,1928,001/geo003/1998,9,Awesome
Book 7,Author 7,1929,001/geo003/1999,10,Awesome
Book 8,Author 8,1930,001/geo003/2000,11,Awesome
Book 9,Author 9,1931,001/geo003/2001,12,Awesome
Book 10,Author 10,1932,001/geo003/2002,13,Awesome
解释
df = pandas.read_csv('./booklist.csv')
df.columns = df.columns.str.replace('.', '', regex=False)
df.columns = df.columns.str.replace(' ', '_', regex=False)
清理csv 文件,使列名中没有空格或.(pandas 真的不喜欢它们,也没有必要)
class main_window:
def __init__(self, root):
self.root = root
root.title("Treeview Search Example")
# Create DataFrame for this window
self.build_df = df.copy()
self.checkout_ids = []
初始化一个类main_window,其中包含您需要的代码。并创建两个变量build_df 和checkout_ids,checkout_ids 将是一个包含您当前“篮子”的列表。 build_df 包含您的 DataFrame (df) 的临时副本,可以根据需要对其进行过滤和移动,而不会影响原始 DataFrame。
# INITIALIZE TREEVIEW + SCROLLVIEW
self.tree = ttk.Treeview(root, columns=list(df.columns.values), show='headings')
self.tree.grid(row=1, column=0, sticky='nsew')
# https://stackoverflow.com/a/41880534/5210078
vsb = ttk.Scrollbar(root, orient="vertical", command=self.tree.yview)
vsb.grid(row=1, column=1, sticky='ns')
self.tree.configure(yscrollcommand=vsb.set)
for column in self.tree['column']:
self.tree.heading(column,text=column)
df_rows = df.to_numpy().tolist()
for row in df_rows:
if row[4] != 0:
self.tree.insert("","end",values=row)
# ADD SEARCH BOXES
search_frame = tk.Frame(root)
search_frame.grid(row=0, column=0, columnspan=2, sticky='nsew')
tk.Label(search_frame, text="TITLE:").grid(row=0, column=0)
tk.Label(search_frame, text="AUTHOR:").grid(row=0, column=2)
tk.Label(search_frame, text="IDENTIFICATION NO:").grid(row=0, column=4)
tk.Label(search_frame, text="SUBJECT CATEGORY:").grid(row=0, column=6)
# Add Search boxes
self.title_ent = tk.Entry(search_frame)
self.title_ent.grid(row=0, column=1)
self.author_ent = tk.Entry(search_frame)
self.author_ent.grid(row=0, column=3)
self.identifaction_ent = tk.Entry(search_frame)
self.identifaction_ent.grid(row=0, column=5)
self.category_ent = tk.Entry(search_frame)
self.category_ent.grid(row=0, column=7)
tk.Button(search_frame, text="Search", command=self.search).grid(row=0, column=10)
tk.Button(search_frame, text="Reseve", command=self.reserve).grid(row=0, column=11)
初始化主 UI,其中包含您的输入框之类的内容。重要的是,使用了if 声明:if row[4] != 0:,因为如果没有可用的书籍,就没有理由显示它们!
def search(self):
# https://stackoverflow.com/a/27068344/5210078
self.tree.delete(*self.tree.get_children())
self.build_df = df.copy()
# https://stackoverflow.com/a/56157729/5210078
entries = [
self.title_ent,
self.author_ent,
self.identifaction_ent,
self.category_ent
]
if entries[0].get():
self.build_df = self.build_df[self.build_df.TITLE.str.contains(entries[0].get())]
if entries[1].get():
self.build_df = self.build_df[self.build_df.AUTHOR.str.contains(entries[1].get())]
if entries[2].get():
self.build_df = self.build_df[self.build_df.SUBJECT_CATEGORY.str.contains(entries[2].get())]
if entries[3].get():
self.build_df = self.build_df[self.build_df.PUBLICATION_DATE == (entries[3].get())]
df_rows = self.build_df.to_numpy().tolist()
for row in df_rows:
print(row)
if row[4] != 0:
self.tree.insert("","end",values=row)
search 系统与previous answer 保持一致!除了如前所述添加的if 语句功能!
储备功能
def reserve(self):
selected = self.tree.item(self.tree.focus())
if selected['values']:
# get the id
book_id = selected['values'][3]
book_id_val = df.loc[df['IDENTIFICATION_NO'] == book_id, 'BOOK_ITEM'].to_numpy().tolist()[0]
if book_id_val < 1:
return 0
else:
self.checkout_ids.append(book_id)
df.loc[df['IDENTIFICATION_NO'] == book_id, 'BOOK_ITEM'] = book_id_val - 1
self.search()
selected = self.tree.item(self.tree.focus())
从self.tree获取当前选中的项目
if selected['values']:
如果有选择项(当没有选择时停止错误)
book_id = selected['values'][3]
从所选项目中获取book_id(第 4 列)并存储它的副本。
book_id_val = df.loc[df['IDENTIFICATION_NO'] == book_id, 'BOOK_ITEM'].to_numpy().tolist()[0]
在 original DataFrame 中找到这本书,并获取其中有多少本书!
if book_id_val < 1:
return 0
如果没有可用的书籍,不要做任何事情,(这是一个备用错误捕获器,因为它不是完全必要的)。
self.checkout_ids.append(book_id)
df.loc[df['IDENTIFICATION_NO'] == book_id, 'BOOK_ITEM'] = book_id_val - 1
self.search()
- 将
id 的副本存储到checkout_ids 列表中
- 将可用书籍的数量减少 1 个
- 重新加载树视图!