Skip to content

Tk backend improvements #17789

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Aug 11, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 10 additions & 8 deletions lib/matplotlib/backends/_backend_tk.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,6 @@ def __init__(self, figure, master=None, resize_callback=None):
# to the window and filter.
def filter_destroy(event):
if event.widget is self._tkcanvas:
self._master.update_idletasks()
self.close_event()
root.bind("<Destroy>", filter_destroy, "+")

Expand All @@ -233,7 +232,6 @@ def resize(self, event):
self._tkcanvas.create_image(
int(width / 2), int(height / 2), image=self._tkphoto)
self.resize_event()
self.draw()

def draw_idle(self):
# docstring inherited
Expand Down Expand Up @@ -383,6 +381,16 @@ def flush_events(self):
# docstring inherited
self._master.update()

def start_event_loop(self, timeout=0):
# docstring inherited
if timeout > 0:
self._master.after(int(1000*timeout), self.stop_event_loop)
self._master.mainloop()

def stop_event_loop(self):
# docstring inherited
self._master.quit()


class FigureManagerTk(FigureManagerBase):
"""
Expand Down Expand Up @@ -527,10 +535,6 @@ def __init__(self, canvas, window, *, pack_toolbar=True):
if pack_toolbar:
self.pack(side=tk.BOTTOM, fill=tk.X)

def destroy(self, *args):
del self.message
tk.Frame.destroy(self, *args)

def set_message(self, s):
self.message.set(s)

Expand All @@ -554,8 +558,6 @@ def set_cursor(self, cursor):
window.configure(cursor=cursord[cursor])
except tkinter.TclError:
pass
else:
window.update_idletasks()

def _Button(self, text, image_file, toggle, command):
image = (tk.PhotoImage(master=self, file=image_file)
Expand Down
2 changes: 0 additions & 2 deletions lib/matplotlib/backends/backend_tkagg.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,10 @@ class FigureCanvasTkAgg(FigureCanvasAgg, FigureCanvasTk):
def draw(self):
super().draw()
_backend_tk.blit(self._tkphoto, self.renderer._renderer, (0, 1, 2, 3))
self._master.update_idletasks()

def blit(self, bbox=None):
_backend_tk.blit(
self._tkphoto, self.renderer._renderer, (0, 1, 2, 3), bbox=bbox)
self._master.update_idletasks()


@_BackendTk.export
Expand Down
1 change: 0 additions & 1 deletion lib/matplotlib/backends/backend_tkcairo.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ def draw(self):
_backend_tk.blit(
self._tkphoto, buf,
(2, 1, 0, 3) if sys.byteorder == "little" else (1, 2, 3, 0))
self._master.update_idletasks()


@_BackendTk.export
Expand Down
29 changes: 29 additions & 0 deletions lib/matplotlib/tests/test_backends_interactive.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,3 +194,32 @@ def test_webagg():
conn.close()
proc.send_signal(signal.SIGINT)
assert proc.wait(timeout=_test_timeout) == 0


@pytest.mark.backend('TkAgg', skip_on_importerror=True)
def test_never_update(monkeypatch, capsys):
import tkinter
monkeypatch.delattr(tkinter.Misc, 'update')
monkeypatch.delattr(tkinter.Misc, 'update_idletasks')

import matplotlib.pyplot as plt
fig = plt.figure()
plt.show(block=False)

# regression test on FigureCanvasTkAgg
plt.draw()
# regression test on NavigationToolbar2Tk
fig.canvas.toolbar.configure_subplots()

# check for update() or update_idletasks() in the event queue
# functionally equivalent to tkinter.Misc.update
# must pause >= 1 ms to process tcl idle events plus
# extra time to avoid flaky tests on slow systems
plt.pause(0.1)

# regression test on FigureCanvasTk filter_destroy callback
plt.close(fig)

# test framework doesn't see tkinter callback exceptions normally
# see tkinter.Misc.report_callback_exception
assert "Exception in Tkinter callback" not in capsys.readouterr().err