Skip to content

Instantly share code, notes, and snippets.

@jni
Created February 23, 2017 01:29
Show Gist options
  • Save jni/ea344f9100bbe6a3e7a3a5c67ea90e87 to your computer and use it in GitHub Desktop.
Save jni/ea344f9100bbe6a3e7a3a5c67ea90e87 to your computer and use it in GitHub Desktop.
Tkinter asyncio matplotlib crash: long-running async tasks using matplotlib and launched by a tkinter GUI
import asyncio
import matplotlib
matplotlib.use('TkAgg')
import tkinter as tk
from tkinter import ttk
from skimage._shared._tempfile import temporary_file
import numpy as np
@asyncio.coroutine
def _async(func, *args):
loop = asyncio.get_event_loop()
return (yield from loop.run_in_executor(None, func, *args))
STANDARD_MARGIN = (3, 3, 12, 12)
def long_computation():
import time
time.sleep(4)
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.imshow(np.random.rand(500, 500))
with temporary_file(suffix='.png') as fname:
fig.savefig(fname)
class MainWindow(tk.Tk):
def __init__(self):
super().__init__()
self.title('I gonna die')
main = ttk.Frame(master=self, padding=STANDARD_MARGIN)
main.grid(row=0, column=0, sticky='nsew')
fsync = long_computation
fasync = lambda: asyncio.ensure_future(_async(long_computation))
# swap in command=fsync instead of fasync below for working slow app
button = ttk.Button(master=main, padding=STANDARD_MARGIN,
text='Run stuff',
command=fasync)
button.grid(row=0, column=0)
main.pack()
def tk_update(loop, app):
try:
app.update()
except tk.TclError as e:
loop.stop()
return
loop.call_later(.01, tk_update, loop, app)
def main():
loop = asyncio.get_event_loop()
app = MainWindow()
#app.mainloop()
tk_update(loop, app)
loop.run_forever()
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment