Matplotlib与Tkinter GUI - 从一个帧到另一个帧的变量

时间:2016-07-14 18:34:04

标签: python python-3.x matplotlib tkinter

现在我想在tkinter GUI中显示matplotlib图,所以我在https://pythonprogramming.net/how-to-embed-matplotlib-graph-tkinter-gui/中关注这个例子。但是,在此示例中,绘制的所有数据都已在GraphPage类中指定。但是对于我的程序,我需要来自StartPage中的条目的信息来计算,使数据适合然后绘制图形。我现在尝试的是将tk.Tk类放入:

def get_page(self, classname):
    '''Returns an instance of a page given it's class name as a string'''
    for page in self.frames.values():
        if str(page.__class__.__name__) == classname:
            return page
    return None

然后在我的GraphPage中添加:

self.controller = controller

startpage = self.controller.get_page("StartPage")

self.iso = startpage.entry1.get()
self.vol = startpage.entry2.get()
self.r = startpage.entry3.get()
self.distance = startpage.selected()

然而,返回给我的是来自StartPage框架的空白条目值。如何从StartPage上的StartPage one按钮获取条目值?

谢谢!!!

编辑:我的代码:

import matplotlib
matplotlib.use("TkAgg")
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure
from lmfit.models import ExponentialGaussianModel
from lmfit import Parameters
from tkinter import messagebox
import matplotlib.pyplot as plt
from numpy import loadtxt
import math

import tkinter as tk
from tkinter import ttk


class PeakFitting(tk.Tk):

    def __init__(self, *args, **kwargs):

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

        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, GraphPage):

            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()

    def get_page(self, classname):
    '''Returns an instance of a page given it's class name as a string'''
        for page in self.frames.values():
            if str(page.__class__.__name__) == classname:
                return page
        return None

class StartPage(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)

        self.controller = controller

        # Setting up frame and widget

        self.v = tk.IntVar()
        self.v.set(1)

        label_det = tk.Label(self, text="Choose Detector")
        self.mcp0 = ttk.Radiobutton(self, text="MCP-0", variable=self.v, value=1, command=self.selected)
        self.mcp6 = ttk.Radiobutton(self, text="MCP-6", variable=self.v, value=2, command=self.selected)
        self.mpet = ttk.Radiobutton(self, text="MCP-MPET", variable=self.v, value=3, command=self.selected)

        label_det.grid(row=0, column=0, columnspan=2)
        self.mcp0.grid(row=1, columnspan=2)
        self.mcp6.grid(row=2, columnspan=2)
        self.mpet.grid(row=3, columnspan=2)

        label_iso = tk.Label(self, text="Isotope A, Element (ex: 133,Cs)")
        label_vol = tk.Label(self, text="Beam Energy (eV)")
        label_range = tk.Label(self, text="Peak Data Range (ex: 1,10.5)")

        label_iso.grid(row=4, column=0)
        label_vol.grid(row=5, column=0)
        label_range.grid(row=6, column=0)

        self.entry1 = tk.Entry(self, validate="key")
        self.entry2 = tk.Entry(self, validate="key")
        self.entry3 = tk.Entry(self, validate="key")

        self.entry1.grid(row=4, column=1)
        self.entry2.grid(row=5, column=1)
        self.entry3.grid(row=6, column=1)

        button3 = ttk.Button(self, text="Graph Page",
                         command=lambda: controller.show_frame(GraphPage))
        button3.grid(row=7, columnspan=2)


    def selected(self):
        if self.v.get() == 1:
            self.x = 8.0
        elif self.v.get() == 2:
            self.x = 3.0
        else:
            self.x = 9.2
        return self.x

class GraphPage(StartPage):
    def __init__(self, parent, controller):

        tk.Frame.__init__(self, parent)
        self.controller = controller

        startpage = self.controller.get_page("StartPage")

        self.iso = startpage.entry1.get()
        self.vol = startpage.entry2.get()
        self.r = startpage.entry3.get()
        self.distance = startpage.selected()

        dict = {'h': 1, 'he': 2, 'li': 3, 'be': 4, 'b': 5, 'c': 6, 'n': 7, 'o': 8, 'f': 9, 'ne': 10,
            'na': 11, 'mg': 12, 'al': 13, 'si': 14, 'p': 15, 's': 16, 'cl': 17, 'ar': 18,
            'k': 19, 'ca': 20, 'sc': 21, 'ti': 22, 'v': 23, 'cr': 24, 'mn': 25, 'fe': 26, 'co': 27, 'ni': 28,
            'cu': 29, 'zn': 30,
            'ga': 31, 'ge': 31, 'as': 33, 'se': 34, 'br': 35, 'kr': 36, 'rb': 37, 'sr': 38, 'y': 39,
            'zr': 40, 'nb': 41, 'mo': 42, 'tc': 43, 'ru': 44, 'rh': 45, 'pd': 46, 'ag': 47, 'cd': 48,
            'in': 49, 'sn': 50, 'sb': 51, 'te': 52, 'i': 53, 'xe': 54, 'cs': 55, 'ba': 56,
            'la': 57, 'ce': 58, 'pr': 59, 'nd': 60, 'pm': 61, 'sm': 62, 'eu': 63, 'gd': 64, 'tb': 65, 'dy': 66,
            'ho': 67, 'er': 68, 'tm': 69, 'yb': 70, 'lu': 71,
            'hf': 72, 'ta': 73, 'w': 74, 're': 75, 'os': 76, 'ir': 77, 'pt': 78, 'au': 79, 'hg': 80, 'tl': 81,
            'pb': 82, 'bi': 83, 'po': 84, 'at': 85, 'rn': 86,
            'fr': 87, 'ra': 88, 'ac': 89, 'th': 90, 'pa': 91, 'u': 92, 'np': 93, 'pu': 94, 'am': 95, 'cm': 96,
            'bk': 97, 'cf': 98, 'es': 99, 'fm': 100, 'md': 101, 'no': 102, 'lr': 103,
            'rf': 104, 'db': 105, 'sg': 106, 'bh': 107, 'hs': 108, 'mt': 109, 'ds': 110, 'rg': 111, 'cn': 112,
            'uut': 113, 'fl': 114, 'uup': 115, 'lv': 116, 'uus': 117, 'uuo': 118}

        button1 = ttk.Button(self, text="Back to Home",
                         command=lambda: controller.show_frame(StartPage))

        button1.grid()

        if self.r == "" or self.iso == "" or self.vol == "":
             return None

        r = self.r
        tup = tuple(int(x) for x in r.split(","))

        iso = self.iso.get()
        iso_list = []
        for e in iso.split(","):
            iso_list.append(e)

        if len(tup) == 2:
            if tup[0] > tup[1]:
                messagebox.showinfo("Error", "Input data range must be from lower to higher time")
                return None

        f = open("mass.mas12.txt", "r")
        i = 0
        while (i < 40):
            header = f.readline()
            i += 1
        self.mass = 0

        # iterate through text file

        for line in f:
            line = line.strip()
            columns = line.split()
            if (list[0] == columns[3]):
                if (list[1].lower() == columns[4].lower()):
                    if (len(columns) == 15):
                        self.mass = float(columns[12].replace("#", "")) + float(columns[13].replace("#", "")) / 10e6
                    else:
                        self.mass = float(columns[11].replace("#", "")) + float(columns[12].replace("#", "")) / 10e6

                    # Calculation

        list = []
        valid = {}
        for q in range(1, 119):
            if q < dict[iso_list[1].lower()]:
                time = (self.distance * math.sqrt(self.mass * 1.6605402e-27 / (2 * q * 1.6022e-19 * float(self.vol)))) * 10e6
                if (time >= float(tup[0])) & (time <= float(tup[1])):
                    list.append(time)
                    valid[time] = q

            # check if charge states of valid time is available for isotope

        if len(valid) == 0:
            messagebox.showinfo("Error", "Change states in range do not exist for given element")
            return None

            # Fit:
            # Query data -> get x, y values... somehow
        data = loadtxt('20160418_1532_scan_1594_step_1_cup_in.csv')
        x = data[:, 0]
        y = data[:, 3]

        mod = None
        p = Parameters()
        i = 0

        for time in list:
            if mod == None:
                mod = ExponentialGaussianModel(prefix='gaussian' + str(i) + '_')
                p.add_many(('gaussian' + str(i) + '_center', time, True, time - 2, time + 2),
                       ('gaussian' + str(i) + '_sigma', 0.15, True, 0),
                       ('gaussian' + str(i) + '_gamma', 0.95, True, 0, 1),
                       ('gaussian' + str(i) + '_amplitude', 50, True, 10))
            else:
                mod = mod + ExponentialGaussianModel(prefix='gaussian' + str(i) + '_')
                p.add_many(('gaussian' + str(i) + '_center', time, True, time - 2, time + 2),
                       ('gaussian' + str(i) + '_sigma', 0.15, True, 0),
                       ('gaussian' + str(i) + '_gamma', 0.95, True, 0, 1),
                       ('gaussian' + str(i) + '_amplitude', 50, True, 10))
            i = i + 1

        out = mod.fit(y, p, x=x)
        fig = Figure(figsize=(5, 5), dpi=100)
        a = fig.add_subplot()
        a.plot(x, y)
        a.plot(x, out.best_fit, 'r-')

        canvas = FigureCanvasTkAgg(fig, self)
        canvas.show()
        canvas.get_tk_widget().pack(side=tk.BOTTOM, fill=tk.BOTH, expand=True)

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




app = PeakFitting()
app.mainloop()

0 个答案:

没有答案