Отображение выпадающего меню в pandastable

#python #pandas #tkinter

Вопрос:

Я визуализирую свой pandas dataframe с pandastable , чтобы посмотреть на данные и изменить их там. Все работает по плану. Теперь я хочу расширить код , чтобы показать мне dropdown menu , когда я редактирую ячейку в отображаемой pandastable . dropdown menu Должны быть представлены значения по умолчанию, которые разрешены в качестве значений ячеек. Например, для column 1 Dataframe возможных значений 1,2 и 3. Есть ли у кого-нибудь идеи, как я могу этого достичь.

Я хотел бы расширить следующий код:

 import tkinter as tk
import sqlite3
from pandastable import Table
import pandas as pd

def save():
    df.to_sql("crawled", conn, if_exists="replace")
    print(df)
    root.quit()

root = tk.Tk()
root.geometry("1500x1000")

frame = tk.Frame(root)
frame.pack(fill="both", expand=True)

df = pd.DataFrame()
df["column1"] = [1,2,3]
df["column2"] = ["a","b","c"]

conn = sqlite3.connect("99_data_increment.db")

pt = Table(frame, dataframe=df, width=300)
pt.show()

button = tk.Button(root, text="Save edits", command=save)
button.pack()

root.mainloop()
 

Ответ №1:

Вам необходимо создать пользовательский класс, производный от pandastable.Table и переопределить drawCellEntry() , чтобы создать выпадающий список, например OptionMenu , вместо Entry виджета по умолчанию в определенной ситуации.

Ниже приведен пример, и вам необходимо изменить его в соответствии с вашими требованиями:

 class MyTable(Table):
    # based on original drawCellEntry() with required changes
    def drawCellEntry(self, row, col, text=None):
        if not self.editable:
            return
        text = self.model.getValueAt(row, col)
        if pd.isnull(text):
            text = ''
        self.cellentryvar = tk.StringVar(value=text)
        if col == 1:
            # if in column 1, use OptionMenu
            self.cellentry = tk.OptionMenu(self.parentframe, self.cellentryvar, 1, 2, 3,
                                           command=lambda x: self.handleCellEntry(row, col))
            self.cellentry.config(font=self.thefont)
        else:
            # else use Entry
            self.cellentry = tk.Entry(self.parentframe, width=20, textvariable=self.cellentryvar, takefocus=1, font=self.thefont)
            self.cellentry.icursor(tk.END)
            self.cellentry.bind('<Return>', lambda x: self.handleCellEntry(row, col))
            self.cellentry.focus_set()
        x1, y1, x2, y2 = self.getCellCoords(row, col)
        self.entrywin = self.create_window(x1, y1, width=x2-x1, height=y2-y1, window=self.cellentry, anchor='nw', tag='entry')

...
# use MyTable instead of Table
pt = MyTable(frame, dataframe=df, width=300)
pt.show()
...