简体   繁体   中英

Converting Pandas DataFrame to tkinter object

I am trying to create a Pandas' DataFrame GUI in tkinter that would update the moment the user changes the value of the cell (each cell is an Entry). I thought that converting the DataFrame into tkinter variables (tk.StringVar, tk.IntVar...) would be the best way to achieve that.

My problem: I am not sure how to convert dataframe into those objects. I tried using the astype function, but it doesn't seem to convert the type.

My questions: 1) how to convert dataframe into tkinter variables?

2) is converting dataframe into ttkinter variables the best way to make the dataframe update instantly?

I think pandas can't use StringVar as dtype .

You would have to get every element in dataframe and create separated var = StringVar(value=df[row,col]) (or var = StringVar() ; var.set(df[row,col])) ) and keep them in standard list.

But you could put values directly to Entry , and bind() event to Entry which will execute function everytime something change in Entry or you press Enter . This function could copy value from Entry to dataframe .


EDIT: example code

It changes value in dataframe when you click Enter (or Enter on keypad) in any Entry .

import pandas as pd
import tkinter as tk

df = pd.DataFrame([[1,2,3], [5,6,7], [101,102,103]])

# --- functions ---

def change(event, row, col):
    # get value from Entry
    value = event.widget.get()
    # set value in dataframe
    df.iloc[row,col] = value
    print(df)

# --- main --    

root = tk.Tk()

# create entry for every element in dataframe

rows, cols = df.shape

for r in range(rows):
    for c in range(cols):
        e = tk.Entry(root)
        e.insert(0, df.iloc[r,c])
        e.grid(row=r, column=c)
        # ENTER 
        e.bind('<Return>', lambda event, y=r, x=c: change(event,y,x))
        # ENTER on keypad
        e.bind('<KP_Enter>', lambda event, y=r, x=c: change(event,y,x))

# start program

root.mainloop()

To change value in dataframe with every key press use <KeyRelease>

(it works when you press Ctrl+V too, so you can paste data from clipboard)

for r in range(rows):
    for c in range(cols):
        e = tk.Entry(root)
        e.insert(0, df.iloc[r,c])
        e.grid(row=r, column=c)
        e.bind('<KeyRelease>', lambda event, y=r, x=c: changed(event, y,x))

EDIT: example as class DataFrameEdit(tk.Frame)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM