Я пытаюсь преобразовать некоторый код с сайта документации matplotlib, который встраивает граф matplotlib в tkinter из модуля, содержащего defs, в модуль, содержащий класс.Этот код взят непосредственно из matplotlib (https://matplotlib.org/gallery/user_interfaces/embedding_in_tk_sgskip.html)) и работает точно так же, как и ожидалось. Однако для моих целей мне нужно это в формате класса, а не в группе определений в модуле. Вот оригинальный код matplotlib:
import tkinter
from matplotlib.backends.backend_tkagg import (
FigureCanvasTkAgg, NavigationToolbar2Tk)
# Implement the default Matplotlib key bindings.
from matplotlib.backend_bases import key_press_handler
from matplotlib.figure import Figure
import numpy as np
root = tkinter.Tk()
root.wm_title("Embedding in Tk")
fig = Figure(figsize=(5, 4), dpi=100)
t = np.arange(0, 3, .01)
fig.add_subplot(111).plot(t, 2 * np.sin(2 * np.pi * t))
canvas = FigureCanvasTkAgg(fig, master=root) # A tk.DrawingArea.
canvas.draw()
canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH,
expand=1)
toolbar = NavigationToolbar2Tk(canvas, root)
toolbar.update()
canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH,
expand=1)
def on_key_press(event):
print("you pressed {}".format(event.key))
key_press_handler(event, canvas, toolbar)
canvas.mpl_connect("key_press_event", on_key_press)
def _quit():
root.quit() # stops mainloop
root.destroy() # this is necessary on Windows to prevent
# Fatal Python Error: PyEval_RestoreThread: NULL
tstate
button = tkinter.Button(master=root, text="Quit", command=_quit)
button.pack(side=tkinter.BOTTOM)
tkinter.mainloop()
# If you put root.destroy() here, it will cause an error if the window
# is closed with the window manager.
Достаточно просто преобразовать часть создания кода этого кода в класс, но я не могу понять, как заставить on_key_press и разделы панели инструментов правильно кодировать.
Это мой код класса, который создает график, но все мои попытки добавления панели инструментов и нажатия клавиш работают безуспешно.
class matplotlibAsClass:
def __init__(self, master):
self.master = master
self.frame = Frame(self.master)
self.create_chart()
self.frame.pack(expand=YES, fill=BOTH)
def create_chart(self):
fig = Figure(figsize=(5, 4), dpi=100)
t = np.arange(0, 3, .01)
fig.add_subplot(111).plot(t, 2 * np.sin(2 * np.pi * t))
canvas = FigureCanvasTkAgg(fig, self.master)
canvas.draw()
canvas.get_tk_widget().pack(side=TOP, fill=BOTH, expand=1)
if __name__ == '__main__':
root = Tk()
matplotlibAsClass(root)
root.mainloop()
Любая помощь по преобразованию полного кода matplotlib, гденажатия клавиш, и панель инструментов работает, в полностью функционирующий класс будет принята с благодарностью.
Вот код, который я написал, который не работает: Следующий код был исправлен и теперь работает правильно.
class matplotlibAsClass:
def __init__(self, master):
self.master = master
self.frame = Frame(self.master)
self.create_chart()
self.frame.pack(expand=YES, fill=BOTH)
def create_chart(self):
self.master.wm_title("Embedding in Tk")
fig = Figure(figsize=(5, 4), dpi=100)
t = np.arange(0, 3, .01)
fig.add_subplot(111).plot(t, 2 * np.sin(2 * np.pi * t))
canvas = FigureCanvasTkAgg(fig, self.master)
canvas.draw()
canvas.get_tk_widget().pack(side=TOP, fill=BOTH, expand=1)
canvas.mpl_connect("key_press_event", self.on_key_press)
toolbar = NavigationToolbar2Tk(canvas, self.master)
toolbar.update()
canvas.get_tk_widget().pack(side=TOP, fill=BOTH, expand=1)
self.button = Button(self.master, text="Quit",command=self._quit)
self.button.pack(side=BOTTOM)
def on_key_press(event):
print("you pressed {}".format(event.key))
key_press_handler(event, canvas, toolbar)
def _quit(self):
self.master.quit() # stops mainloop
#self.master.destroy()
if __name__ == '__main__':
root = Tk()
matplotlibAsClass(root)
root.mainloop()
когда я запускаю этот код, я получаю следующую ошибку:
File
"/Users/Me/Mee/python_db_programs/simpletestgui_sc_two.py",
line 104, in create_stockchart
canvas.mpl_connect("key_press_event", on_key_press)
NameError: name 'on_key_press' is not defined
После изменения on_key_press to self.on_key_press Я получаю следующую ошибку:
File "/Users/Me/Mee/python_db_programs/simpletestgui_sc_two.py", line
111, in create_stockchart
self.button = Button(self.master,
text="Quit",command=self._quit())
TypeError: _quit() takes 0 positional arguments but 1 was given
После исправления def _quit () для def _quit (self) я получаю следующую ошибку:
File
"/Users/Me/Mee/python_db_programs/simpletestgui_sc_two.py",
line 111, in create_stockchart
self.button = Button(self.master, text="Quit",
command=self._quit())
_tkinter.TclError: can't invoke "button" command: application has been
destroyed
На основепредыдущая ошибка Я закомментировал часть self.master.destroy () в def _quit, и теперь диаграмма загружается, и панель инструментов работает, но кнопка выхода на самом деле не приводит к закрытию виджета.
Окончательное исправление, который я не полностью уловил из предыдущего комментария, это изменить command = self._quit () на command = self._quit, и теперь все работает правильно.