Преобразовать вложение Matplotlib в код tkinter из defs в класс - PullRequest
0 голосов
/ 20 декабря 2018

Я пытаюсь преобразовать некоторый код с сайта документации 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, и теперь все работает правильно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...