Matplotlib mit Tkinter verbinden und verwenden
Posted: 29 Dec 2024, 10:29
Ich habe Code geschrieben, der mithilfe von Blit ein Bild zeichnet, wenn Sie auf den Bildschirm klicken.
Wenn matplotlib alleine verwendet wird, funktioniert es normal.
Allerdings, wenn es mit tkinter verbunden ist , das Klickereignis wird nicht übermittelt.
Wenn Lambda verwendet wird, wird ein Klickereignis gesendet, aber das Bild wird nicht gezeichnet.
Auch wenn Sie ein Ereignis ohne a verbinden Lambda, der Rückruf wird nicht Arbeit.
Was ist das Problem?
Wenn matplotlib alleine verwendet wird, funktioniert es normal.
Allerdings, wenn es mit tkinter verbunden ist , das Klickereignis wird nicht übermittelt.
Wenn Lambda verwendet wird, wird ein Klickereignis gesendet, aber das Bild wird nicht gezeichnet.
Auch wenn Sie ein Ereignis ohne a verbinden Lambda, der Rückruf wird nicht Arbeit.
Was ist das Problem?
Code: Select all
import tkinter as tk
import matplotlib.pyplot as plt
from matplotlib.backends.backend_agg import FigureCanvasAgg
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.collections import LineCollection
xy = [
[
(0, 0),
(1, 1),
(2, 2),
(3, 3),
(4, 2),
(5, 1),
(6, 0),
],
[
(7, 0),
(8, 1),
(9, 2),
(10, 3),
(11, 2),
(12, 1),
(13, 0),
],
]
class Blit:
bg = None
cbg = False
was_draw = False
def __init__(self):
self.fig, self.ax = plt.subplots(1, 1)
self.canvas: FigureCanvasAgg = self.fig.canvas
self.ax.set_xlim(0, 20)
self.ax.set_ylim(0, 10)
self.lc = LineCollection(xy, edgecolors=['y', 'b'], facecolors=['r', 'g'], alpha=[0.2, 1], linewidth=15, animated=True)
self.ax.add_collection(self.lc)
self.connect_event()
return
def connect_event(self):
self.canvas.mpl_connect('button_press_event', self.draw_artist)
return
def create_bg(self):
if self.cbg: return
self.cbg = True
self.bg = self.canvas.copy_from_bbox(self.fig.bbox)
self.cbg = False
return
def draw_artist(self, _):
print()
print('draw_artist')
if not self.bg: self.create_bg()
self.canvas.restore_region(self.bg)
if self.was_draw:
self.was_draw = False
self.lc.set_visible(False)
return self.blit()
print('draw')
self.was_draw = True
self.lc.set_visible(True)
return self.blit()
def blit(self):
self.ax.draw_artist(self.lc)
self.canvas.blit()
return
class TkBlit:
def __init__(self, master):
self.f = tk.Frame(master)
self.f.grid(column=0, row=0)
self.b = Blit()
tkagg = FigureCanvasTkAgg(self.b.fig, self.f)
tkagg.draw()
widget = tkagg.get_tk_widget()
# if use lambda, event work.
# self.b.canvas.mpl_connect('button_press_event', lambda x: self.b.draw_artist(x))
widget.grid(column=0, row=0)
return
plt.switch_backend('tkagg')
b = Blit()
plt.show()
window = tk.Tk()
TkBlit(window)
window.protocol("WM_DELETE_WINDOW", lambda *_: (plt.close('all'), window.destroy()))
window.mainloop()