Помещение постоянно обновляемого анимированного сюжета с другими компонентами в графический интерфейс tkinter - PullRequest
2 голосов
/ 02 апреля 2019

Я хочу показать график на одной из страниц моего GUI.Данные, нанесенные, theData будут постоянно меняться.Всякий раз, когда theData изменяется, значение valueChangedtheData записывается в 1. Отображение времени и данных здесь:

xsize=100
xdata,ydata = [],[]
def data_gen():
    t = data_gen.t
    global theData
    global valueChangedtheData
    while True:
        if (valueChangedtheData == 1):
           valueChangedtheData = 0;
           t+=0.1
           val=float(theData);
           if val>1000:
               continue
           yield t, val

        else: pass


def animate(data):
    t, val = data
    if t>-1:
        xdata.append(t)
        ydata.append(val)
        if t>xsize: # Scroll to the left.
            a.set_xlim(t-xsize, t)
        line.set_data(xdata, ydata)
    return line,

def on_close_figure(event):
    sys.exit(0)

data_gen.t = -1
f = plt.figure()
f.canvas.mpl_connect('close_event', on_close_figure)
#f = Figure(figsize=(5,5), dpi=100)
a = f.add_subplot(111)
line, = a.plot([], [], lw=2)
a.set_ylim(0, 250)
a.set_xlim(0, xsize)
a.grid()

Я определил свой контейнер моего графического интерфейса следующим образом:

class Gui(Tk):
    def __init__(self, *args, **kwargs):
        Tk.__init__(self, *args, **kwargs)
        container = Frame(self)
        container.pack(side="top", fill = "both", expand = TRUE)
        container.grid_rowconfigure(0, weight = 1)

        global theData;


        self.MyReading = StringVar()
        self.frames={}

        for F in (StartPage, PageOne):
            frame = F(container, self)
            self.frames[F] = frame
            frame.grid(row = 0, column = 0, sticky = "nsew")

        self.show_frame(StartPage)

    def show_frame(self, cont):
      frame = self.frames[cont]
      frame.tkraise()

и страница, показывающая сюжет:

class StartPage(Frame):                         #The Graphical Page
    def __init__(self, parent, controller):
        Frame.__init__(self,parent)

        label = Label(self, text="StartPage")
        label.pack()
        label1 = Label(self, textvariable = controller.theData)
        label1.pack

        canvas = FigureCanvasTkAgg(f, self)
        canvas.draw() #changed from show to draw
        canvas.get_tk_widget().pack(side=BOTTOM, fill=BOTH, expand=True)

        toolbar = NavigationToolbar2Tk(canvas, self)
        toolbar.update()
        canvas._tkcanvas.pack(side=TOP, fill=BOTH, expand=True)

А для того, чтобы запустить анимацию и Gui:

root = Gui()
update_reading()
ani = animation.FuncAnimation(f, animate, data_gen, blit = False, interval=100, repeat = False)
root.mainloop()

С update_reading() при обновлении метки:

def update_reading():
    global theData
    global valueChangedtheData
    theData = randint(1,20)             #This is just an example of the changing value
    print(theData)
    valueChangedtheData = 1;
    root.MyReading.set(str(theData));
    root.after(100,update_reading)

Однако после добавления холста на страницу все метки, использующие переменные классы, откажутся от покупки, включая значение для theData, но график отображается.Кроме того, ярлыки, которые показывают изображения, также отказываются появляться.После комментирования холста, отображения данных и анимации метка появится снова.Я пропустил важный инициализирующий код?Кроме того, во время построения графика в окне графического интерфейса происходит значительная «медлительность».Может ли это быть облегчено благодаря лучшему написанию кода?Спасибо

Импорт:

from tkinter import *

import matplotlib
matplotlib.use("TkAgg")
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
from matplotlib.figure import Figure
import matplotlib.animation as animation
import matplotlib.pyplot as plt
import numpy as np
from matplotlib import style
from random import randint

РЕДАКТИРОВАТЬ: Добавлен пропущенный и необходимый код. РЕДАКТИРОВАТЬ2: Включен весь импорт

...