Display of a dropdown menu in pandastable

I am visualizing my pandas dataframe with pandastable to look at the data and modify it there. This works as planned. Now I want to extend the code to show me a dropdown menu, when I edit the cell in the displayed pandastable. The dropdown menu should present default values that are allowed as cell values. For example, for column 1 of the Dataframe possible values are 1,2 and 3. Does anyone have any idea how I can achieve this.

I would like to extend the following code:

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 answer

  • answered 2021-10-25 05:47 acw1668

    You need to create custom class derived from pandastable.Table and override the drawCellEntry() to create a dropdown list, for example OptionMenu, instead of default Entry widget under certain situation.

    Below is an example and you need to modify it to suit your requirement:

    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()
    ...
    

How many English words
do you know?
Test your English vocabulary size, and measure
how many words do you know
Online Test
Powered by Examplum