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