现在我想在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()