【问题标题】:Get treeview row and put it into another treeview in another root获取树视图行并将其放入另一个根中的另一个树视图中
【发布时间】:2022-01-05 02:13:07
【问题描述】:

我在我的图书馆管理系统中做了一个结帐功能。它旨在让用户从给定的树视图中选择书籍: 我的目标是获取用户单击的数据行并将“添加到购物车”按到另一个带有树视图的窗口:。仅添加他们从主页中选择的特定图书行数据。这是我的树视图代码:

reserve_button = Button(text="RESERVE" ,fg=WHITE, bg=NAVY_BLUE, width=20, command=reserve)
                reserve_button.grid(column=5,row=5)
                checkout_button = Button(text="CHECKOUT", fg=WHITE,bg="#6DA5A9",width=20,command=checkout_page)
                checkout_button.grid(column=0,row=5,sticky="w")
                search_button = Button(text="SEARCH", fg=WHITE,bg="pink", width=20, command=search)
                search_button.grid(column=3,row=3)
                add_to_cart = Button(text="ADD TO CART", fg=WHITE,bg="#7E370C", width=20,command=add_to_cart_f)
                add_to_cart.grid(column=7, row=5,sticky="e")


                tree = ttk.Treeview()
                books_data = pandas.read_csv("List of Books - Sheet1 (3).csv")
                df_column = books_data.columns.values
                print(len(df_column))
                print(df_column)
                tree["column"] = list(books_data.columns)
                tree["show"] = "headings"
                vsb = ttk.Scrollbar(orient="vertical", command=tree.yview())
                vsb.grid(column=8, row=4, sticky="ns")
                tree.configure(yscrollcommand=vsb.set)

                for column in tree['column']:
                    tree.heading(column,text=column)

                df_rows = books_data.to_numpy().tolist()
                for row in df_rows:
                    tree.insert("","end",values=row)
                tree.grid(column=0,row=4,columnspan=8)

【问题讨论】:

    标签: python pandas tkinter


    【解决方案1】:

    简短的回答

    我创建了一个使用它的示例项目:

    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_dfcheckout_idscheckout_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 个
    • 重新加载树视图!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多