user3517818
user3517818

Reputation: 108

tkinter .after() function is not pausing

When I try to run my code everything executes but the after function calls update immediately, despite the 5 second delay I put in. On top of this, the gui does not show any graph.

import tkinter as tk
import numpy as np
import time
import functools

import matplotlib
matplotlib.use("TkAgg")
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure

main = tk.Tk()
container = tk.Frame(main)
container.pack(side="top", fill="both", expand = True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)

f = Figure(figsize=(5,5), dpi=100)
a = f.add_subplot(111)
canvas = FigureCanvasTkAgg(f, master=main)
canvas.show()
canvas.get_tk_widget().pack(side=tk.BOTTOM, fill=tk.BOTH, expand=True)

def update(a, canvas):
        data = np.genfromtxt('test.csv', delimiter=',', names=['x', 'y'])
        a.clear()
        a.plot(data['x'], data['y'], color='r', label='the data')


        canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=True)

        print ("update")
        main.after(5000, functools.partial(update, a)(canvas))

main.after(5000, functools.partial(update, a)(canvas))
main.mainloop()

Any help on solving this issue or just general python tips would be greatly appreciated.

Upvotes: 0

Views: 498

Answers (1)

Bryan Oakley
Bryan Oakley

Reputation: 386010

Consider this line of code:

main.after(5000, functools.partial(update, a)(canvas))

It is doing exactly the same thing as this:

func = functools.partial(update, a)
result = func(canvas)
main.after(5000, result)

In order for after to do its job you must give it a reference to the function to be called. In your code you're actually calling it immediately and then passing the result to after.

Since you can supply positional arguments to after which will get passed on to your command, you can rewrite your after like this:

main.after(5000, functools.partial(update, a), canvas)

Though, I don't quite see why you think you need functools.partial. You should be able to condense it down to this:

main.after(5000, update, a, canvas)

Upvotes: 1

Related Questions