在 tkinter 中过滤基于 pandas 数据框的树视图,无法按预期工作

问题描述 投票:0回答:1

所以,这是我的问题:

我用股票数据构建了一个数据框dfAcciones。将数据添加到名为 tabla:

的树视图变量中

为了做到这一点,我有一个功能可以清理数据帧,另一个功能可以通过按钮显示数据帧信息:

        def limpiar_dataframe():

            for item in tabla.get_children():
                tabla.delete(item)

        def datos_excel():

            limpiar_dataframe()

            tabla['column'] = list(dfAcciones.columns)
            tabla['show'] = "headings"
            for columna in tabla['column']:
                tabla.heading(columna, text=columna)
                df_fila = dfAcciones.to_numpy().tolist()
            for fila in df_fila:
                tabla.insert('', 'end', values = fila)

        tabla = ttk.Treeview(main_window_acciones, height=15)
        tabla.place(x=10, y=400, width=800, height=400)
        ladox = Scrollbar(main_window_acciones, orient= HORIZONTAL, command=tabla.xview)
        ladox.place(x=10, y=370, width=800, height=25) 
        ladoy = Scrollbar(main_window_acciones, orient= VERTICAL, command=tabla.yview)
        ladoy.place(x=820, y=400, width=25, height=400) 
        tabla.configure(xscrollcommand=ladox.set, yscrollcommand=ladoy.set)

        botonmostrar = Button(main_window_acciones, text='Mostrar', command=datos_excel)
        botonmostrar.place(x=80, y=340) 



Image of how the data is shown in the tkinter

一旦数据全部显示在 tkinter 窗口中,我就使用上面在图像中看到的过滤器,例如 PEG 比率、公司名称和部门名称。所有过滤器都可以工作,这就是我构建它们的方式:

首先是要过滤的按钮:

        text_nombre = tk.Label(widgets_frame_filtros, text="Nombre empresa: ")
        text_nombre.grid(row=0, column=0, padx=5, pady=5, sticky="ew")
        name_entry = ttk.Entry(widgets_frame_filtros)
        name_entry.insert(0, "Name")
        name_entry.bind("<FocusIn>", lambda e: name_entry.delete('0', 'end'))
        name_entry.grid(row=0, column=1, padx=5, pady=(0, 5), sticky="ew")

        text_sector = tk.Label(widgets_frame_filtros, text="Escoge PEG Ratio: ")
        text_sector.grid(row=1, column=0, padx=5, pady=5, sticky="ew")
        peg_ratio_spinbox = ttk.Spinbox(widgets_frame_filtros, from_=0, to=250, increment=.1)
        peg_ratio_spinbox.insert(0, "0")
        peg_ratio_spinbox.grid(row = 1, column = 1, padx=5, pady=5, sticky = "ew")

        text_sector = tk.Label(widgets_frame_filtros, text="Escoge Sector: ")
        text_sector.grid(row=2, column=0, padx=5, pady=5, sticky="ew")
        sectorname_list = ["All", "Atención sanitaria", "Bienes raíces", "Energía", "Industria", "Materiales básicos","Productos de consumo cíclicos", "Productos de consumo defensivos", "Servicios de comunicaciones", "Servicios financieros", "Servicios públicos", "Tecnología"]
        sector_name_combobox = ttk.Combobox(widgets_frame_filtros, values=sectorname_list)
        sector_name_combobox.current(0)
        sector_name_combobox.grid(row=2, column=1, padx=5, pady=5, sticky="ew")


其次,我有一个按钮,一旦设置过滤器,就会“更新”表格:

        botonrefresh = Button(main_window_acciones, text='Actualizar', command=actualiza_ventana)
        botonrefresh.place(x=750, y=340) 

第三,一旦使用“更新”表格的按钮,我们就继续过滤信息:

def actualiza_ventana():

            limpiar_dataframe()

            name = name_entry.get()
            peg_ratio = float(peg_ratio_spinbox.get())
            sector_name = sector_name_combobox.get()

            dfAcciones1 = pd.DataFrame()
            dfAcciones2 = pd.DataFrame()
            dfAcciones3 = pd.DataFrame()

            if sector_name != 'All':
                dfAcciones1=dfAcciones.query("SectorName==@sector_name")
                sector_name_combobox.set(sectorname_list[0])
                
                tabla['column'] = list(dfAcciones1.columns)
                tabla['show'] = "headings"
                for columna in tabla['column']:
                    tabla.heading(columna, text=columna)
                    df_fila = dfAcciones1.to_numpy().tolist()
                for fila in df_fila:
                    tabla.insert('', 'end', values = fila)


            if name != 'Name':
                dfAcciones2 = dfAcciones[dfAcciones['Name'].str.contains(name)]
                name_entry.delete(0, "end")
                name_entry.insert(0, "Name")

                tabla['column'] = list(dfAcciones2.columns)
                tabla['show'] = "headings"
                for columna in tabla['column']:
                    tabla.heading(columna, text=columna)
                    df_fila = dfAcciones2.to_numpy().tolist()
                for fila in df_fila:
                    tabla.insert('', 'end', values = fila)
        

                    
            if peg_ratio != "0":
                dfAcciones3 = dfAcciones.query("PEGRatio >= @peg_ratio")
                peg_ratio_spinbox.delete(0, "end")
                peg_ratio_spinbox.insert(0, "0")

                tabla['column'] = list(dfAcciones3.columns)
                tabla['show'] = "headings"
                for columna in tabla['column']:
                    tabla.heading(columna, text=columna)
                    df_fila = dfAcciones3.to_numpy().tolist()
                for fila in df_fila:
                    tabla.insert('', 'end', values = fila)

一旦数据帧被过滤,问题就出现了,当我过滤peg_ratio时,树视图被正确过滤并按预期显示: Image of peg_ratio filter

但是,当我按公司名称或部门进行过滤时,过滤器无法按预期工作,并显示过滤后的数据加上之前存在的数据框: Image of company name filter

我不明白问题是什么以及如何解决。

python dataframe tkinter filter treeview
1个回答
0
投票

请注意,

peg_ratio
actualiza_ventana()
内部的浮点数,因此检查
peg_ratio != "0"
将始终被评估为True。

将检查更改为

peg_ratio != 0.0
将解决该问题。

© www.soinside.com 2019 - 2024. All rights reserved.