分别运行部分代码以防止Tkinter窗口冻结

时间:2019-05-03 14:06:55

标签: python multithreading matplotlib tkinter

我有一个Tkinter GUI,它使用Canvas显示图表。图表的数据来自数据框。显示图表需要大量时间,在此期间Tkinter窗口将被冻结。 我尝试了多线程,但不确定如何在代码中实现。

能否请您告诉我如何避免这种情况?我只附加部分代码。

import tkinter as tk  # python 3
from tkinter import font  as tkfont  # python 3
from matplotlib.figure import Figure as Fg
from tkinter import filedialog
from tkinter import tkentrycomplete
import tkinter.messagebox as tm
from ttkthemes import themed_tk as thtk
from tkinter import ttk, Canvas
from matplotlib.backends.backend_tkagg \
    import FigureCanvasTkAgg, NavigationToolbar2Tk
import matplotlib.pyplot as plt
from PIL import ImageTk, Image
import pandas as pd


class SampleApp(tk.Tk):

    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)

        self.title_font = tkfont.Font(family='Helvetica', size=18, weight="bold", slant="italic")

        # the container is where we'll stack a bunch of frames
        # on top of each other, then the one we want visible
        # will be raised above the others
        container = tk.Frame(self)
        container.pack(side="top", fill="both", expand=True)
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)

        self.frames = {}
        for F in (StartPage, PageOne, PageTwo):
            page_name = F.__name__
            frame = F(parent=container, controller=self)
            self.frames[page_name] = frame

            # put all of the pages in the same location;
            # the one on the top of the stacking order
            # will be the one that is visible.
            frame.grid(row=0, column=0, sticky="nsew")

        self.show_frame("StartPage")

    def show_frame(self, page_name):
        '''Show a frame for the given page name'''
        frame = self.frames[page_name]
        frame.tkraise()

    class StartPage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        label = tk.Label(self, text="This is the start page", font=controller.title_font)
        label.pack(side="top", fill="x", pady=10)

        button1 = tk.Button(self, text="Go to Page One",
                            command=lambda: controller.show_frame("PageOne"))
        button2 = tk.Button(self, text="Go to Page Two",
                            command=lambda: controller.show_frame("PageTwo"))
        button1.pack()
        button2.pack()


class PageOne(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        label = tk.Label(self, text="This is page 1", font=controller.title_font)
        label.pack(side="top", fill="x", pady=10)
        button = tk.Button(self, text="Go to the start page",
                           command=lambda: controller.show_frame("StartPage"))
        button.pack()
        self.fig = Fg(figsize=(11.5, 4.6), dpi=100)
        self.fig.subplots_adjust(
            top=0.85, bottom=0.19, right=0.97, left=0.11)
        self.fig.suptitle(
            'By ' + self.labels[self.ID].cget('text'),
            fontweight='bold', fontsize=11)
        plt.rcParams.update({'font.size': 7})
        # self.fig.autofmt_xdate(rotation=30)
        self.canvas = FigureCanvasTkAgg(self.fig, self)
        self.canvas.get_tk_widget().place(x=50, y=240)
        self.canvas.get_tk_widget().config(relief=tk.RAISED)
        self.toolbar_frame = tk.Frame(master=self, height=20)
        self.toolbar_frame.place(x=500, y=700)
        self.toolbar = NavigationToolbar2Tk(
            self.canvas, self.toolbar_frame)
        self.toolbar.config(background='#009da6')
        self.toolbar._message_label.config(background='#009da6')
        self.toolbar.update()
        for button in self.toolbar.winfo_children():
            button.config(background='#464646')
        self.ax = self.fig.add_subplot(111)
        self.ax.grid()
        self.ax.format_coord = lambda x, y: ""
        self.string = ''
        for k, v in dm.items():
            self.string = self.string + "{}:{}, ".format(k, v)
        self.ax.text(0.2, 0.85, r'Filters:  ', ha='center', va='center',
                     transform=plt.gcf().transFigure,
                     fontsize=9, color='green')
        self.ax.text(0.25, 0.85, self.string[:-2], ha='left', va='center',
                     transform=plt.gcf().transFigure, fontsize=9)
        self.ax.set_ylabel(self.yLabel)

        self.df.plot(x=self.labels[self.ID].cget(
        'text'), ax=self.ax, kind="bar", fontsize=7, grid=True)
        plt.setp(self.ax.get_xticklabels(), rotation=30,
             horizontalalignment='right')
        self.box = self.ax.get_position()
        self.ax.set_position(
        [self.box.x0, self.box.y0,
         self.box.width * 0.9, self.box.height])
        self.ax.legend(loc='center left', bbox_to_anchor=(1, 0.5))
        self.canvas.draw()


if __name__ == "__main__":
    app = SampleApp()
    app.mainloop()

0 个答案:

没有答案