Фильтр pandas dataframe, отображаемый в tkinter / pandastable - PullRequest
0 голосов
/ 16 декабря 2018

Я пытаюсь создать приложение, которое включает отображение кадра данных среднего размера для панд.Я использую pandastable и tkinter для моего пользовательского интерфейса.Часть того, что я хочу, чтобы пользователь мог сделать, это выбрать фильтр из комбинированного списка и затем отображать только совпадающие строки.

Ниже приведена упрощенная, но полная версия кода, который я пытаюсь использовать.Я создаю класс, в котором есть основной код пользовательского интерфейса.Изначально все выглядит отлично.Я создал функцию тестовой кнопки внутри моего класса (change_df), которая создает фиктивный столбец, который работает нормально.У меня есть другая функция внутри класса (change_df_combo), которая успешно фильтрует фрейм данных, но он не отображается на экране.Т.е. я могу распечатать df или экспортировать его, и он отфильтрован.Однако это не отображается на экране.

Я полагаю, что мой класс или сам tkinter не работают правильно, но я не могу понять это ради своей жизни!Есть мысли?

from win32com.shell import shell, shellcon
import pandas as pd
import openpyxl
from openpyxl import load_workbook
import numpy as np
import time
from tkinter import *
from tkinter import ttk
from pandastable import Table, TableModel

class UserInterface(Frame):
    # Launch the df in a pandastable frame
    def __init__(self, parent=None):
        global ui_df
        global pt
        ui_df = pos_df
        self.parent = parent
        Frame.__init__(self)
        self.main = self.master
        #self.main.geometry('800x600+0+0')
        f = Frame(self.main)
        f.grid(column=0, row=1, sticky=(E, W))
        screen_width = f.winfo_screenwidth() * 0.8
        screen_height = f.winfo_screenheight() * 0.7
        self.table = pt = Table(f, dataframe=ui_df, height = screen_height, width = screen_width)
        pt.show()
        return

    def change_df(self, col_val_input):
        #Responds to button
        ui_df['Test col'] = col_val_input
        pt.show()

    def change_df_combo(self, event):
        #Responds to combobox, supposed to filter by 'Sec_type'
        combo_selection = str(combo_box.get())
        ui_df = pos_df[pos_df['Sec_type'] == combo_selection]
        pt.show()

#Create dataframe
pos_data = {'Location' : ['Denver', 'Boulder', 'Phoenix', 'Reno', 'Portland',
'Eugene', 'San Francisco'], 'Sec_type' : ['mbus', 'mbus', 'vmus', 'caus',
'vmus', 'mbus', 'mbus']}
pos_df = pd.DataFrame(data = pos_data)

#Launch Tkinter basics
root = Tk()
root.title("S test...")

mainframe = ttk.Frame(root, padding="3 3 12 12")
mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
mainframe.columnconfigure(0, weight=1)
mainframe.rowconfigure(0, weight=1)
root.columnconfigure(0, weight=1)
root.rowconfigure(0, weight=1)

ui_display = UserInterface(mainframe)

#'Test' button, this works fine
col_val_input = 'It worked!'
test_button = ttk.Button(mainframe, text = 'Test', command= lambda: ui_display.change_df(col_val_input))
test_button.grid(column=0, row=0, sticky=(W))

#Combobox, works to just show choice, but not to filter
combo_choices = ['mbus', 'vmus', 'caus']
choice = StringVar()
combo_box = ttk.Combobox(mainframe, textvariable=choice)
combo_box['values'] = combo_choices
combo_box.grid(column=1, row=0, sticky=(W))
combo_box.bind('<<ComboboxSelected>>', ui_display.change_df_combo)

root.mainloop()

Редактировать, чтобы добавить: Изменен импортированный df на игрушечный df для целей тестирования

1 Ответ

0 голосов
/ 21 декабря 2018

Хорошо, я придумал что-то, что работает.Не уверен, что это самый питонский код, когда-либо написанный, но здесь он идет: (публикуя только сегмент класса)

class UserInterface(Frame):
    # Launch the df in a pandastable frame
    def __init__(self, parent=None):
        global ui_df
        ui_df = pos_df
        self.parent = parent
        self.refresh_df(df = ui_df)

    def refresh_df(self, df):
        Frame.__init__(self)
        self.main = self.master
        f = Frame(self.main)
        f.grid(column=0, row=1, sticky=(E, W))
        screen_width = f.winfo_screenwidth() * 0.8
        screen_height = f.winfo_screenheight() * 0.7
        self.table = pt = Table(f, dataframe=df, height = screen_height, width = screen_width)
        pt.show()
        return

    def change_df(self, col_val_input):
        #Responds to button
        ui_df['Test col'] = col_val_input
        self.refresh_df(df=ui_df)

    def change_df_combo(self, event):
        #Responds to combobox, supposed to filter by 'Sec_type'
        combo_selection = str(combo_box.get())
        ui_df = pos_df[pos_df['Sec_type'] == combo_selection]
        ui_df['Test col combo'] = combo_selection
        self.refresh_df(df=ui_df)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...