Update table content using pandastable (Python, tkinter)

Viewed 1597

I have a dataframe being displayed in a gui as a table using pandastable. I would like to have this table be frequently updates as new data becomes available (which updates the dataframe columns).

So I wrote this simple example to illustrate the point:

I create the dataframe df, then update it twice in the program by waiting 5 secs between each updates. I expect the GUI to appear then the contents to be updated at the same cadence. Instead the program execute with only the final dt value showing up in the table.

I tried to use .update() and .redraw() instead of .show() to update the values but that didn't work either.

Your input is much appreciated!

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

df = pd.DataFrame({
    'A': [1,1,1,1,1,1,],
    'B': [1,1,1,1,1,1,],
    'C': [1,1,1,1,1,1,],
    'D': [1,1,1,1,1,1,],
})

root = tk.Tk()
root.title('PandasTable Example')

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

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

time.sleep(5)

df = pd.DataFrame({
    'A': [2,2,2,2,2,2,],
    'B': [2,2,2,2,2,2,],
    'C': [2,2,2,2,2,2,],
    'D': [2,2,2,2,2,2,],
})

pt.model.df = df
pt.show()

time.sleep(5)

df = pd.DataFrame({
    'A': [3,3,3,3,3,3,],
    'B': [3,3,3,3,3,3,],
    'C': [3,3,3,3,3,3,],
    'D': [3,3,3,3,3,3,],
})

pt.model.df = df
pt.show()

root.mainloop()



1 Answers

mainloop starts GUI - it shows/display window. Everything before mainloop is only information for mainloop what it has to display.

You can use root.update() to force mainloop() to redraw window.

Or you can use root.after(milliseconds, function_name) instead of sleep and it will run code after running mainloop

You can also use pt.readraw instead of pt.show after updating pd.model.df - it will not flick.

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

# --- function ---

def update1():
    df = pd.DataFrame({
        'A': [2,2,2,2,2,2,],
        'B': [2,2,2,2,2,2,],
        'C': [2,2,2,2,2,2,],
        'D': [2,2,2,2,2,2,],
    })
    
    pt.model.df = df
    #pt.show()
    pt.redraw()

    root.after(5000, update2)
        
def update2():
    
    df = pd.DataFrame({
        'A': [3,3,3,3,3,3,],
        'B': [3,3,3,3,3,3,],
        'C': [3,3,3,3,3,3,],
        'D': [3,3,3,3,3,3,],
    })
    
    pt.model.df = df
    #pt.show()
    pt.redraw()
    
# --- main ---
    
df = pd.DataFrame({
    'A': [1,1,1,1,1,1,],
    'B': [1,1,1,1,1,1,],
    'C': [1,1,1,1,1,1,],
    'D': [1,1,1,1,1,1,],
})

# - gui -

root = tk.Tk()
root.title('PandasTable Example')

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

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

root.after(5000, update1)

root.mainloop()

If you will run the same code then you could use after to run the same function.

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

# --- function ---

def update():
    
    pt.model.df += 1
    pt.redraw()
    
    # run again after 5000ms (5s)
    root.after(5000, update)
    
# --- main ---
    
df = pd.DataFrame({
    'A': [1,1,1,1,1,1,],
    'B': [1,1,1,1,1,1,],
    'C': [1,1,1,1,1,1,],
    'D': [1,1,1,1,1,1,],
})

# - gui -

root = tk.Tk()
root.title('PandasTable Example')

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

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

root.after(5000, update)

root.mainloop()

You can see more on my blog in article Tkinter PandasTable Examples [GB]

Related