I looked at similar problems, but I could not find solutions for my mistake in them.
Problem:
In the StartPage
block, I enter the data for the graph, which is based on these values in the PageOne
block, but the data of the first block cannot be used in the second block. They need to ask something either global
or nonlocal
, but I don’t know where to insert it.
import matplotlib
from math import *
import pylab
from matplotlib import mlab
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure
import tkinter as tk
from tkinter import ttk
from tkinter import *
g = 9.81
class Fly(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
tk.Tk.wm_title(self, "Fly")
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):
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(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="Начальная страница")
label.pack(pady=10, padx=10)
button = ttk.Button(self, text="Visit Page 1",
command=lambda: controller.show_frame(PageOne))
button.pack()
v = IntVar()
angle = IntVar()
x0 = IntVar()
y0 = IntVar()
v2 = IntVar()
angle2 = IntVar()
x02 = IntVar()
y02 = IntVar()
v3 = IntVar()
angle3 = IntVar()
x03 = IntVar()
y03 = IntVar()
frame2 = Frame(self, borderwidth=4, relief=GROOVE)
frame2.pack()
first = Label(self, text='Данные для первого графика')
first.pack()
second = Label(self, text='Начальная скорость')
second.pack()
entry = Entry(self, width=10, textvariable=v)
entry.pack()
third = Label(self, text='Угол выстрела')
third.pack()
entry = Entry(self, width=10, textvariable=angle)
entry.pack()
fourth = Label(self, text='Начальная координата x')
fourth.pack()
entry = Entry(self, width=10, textvariable=x0)
entry.pack()
fifth = Label(self, text='Начальная координата y')
fifth.pack()
entry = Entry(self, width=10, textvariable=y0)
entry.pack()
frame3 = Frame(self, borderwidth=4, relief=GROOVE)
frame3.pack()
first = Label(self, text='Данные для второго графика')
first.pack()
second = Label(self, text='Начальная скорость')
second.pack()
entry = Entry(self, width=10, textvariable=v2)
entry.pack()
third = Label(self, text='Угол выстрела')
third.pack()
entry = Entry(self, width=10, textvariable=angle2)
entry.pack()
fourth = Label(self, text='Начальная координата x')
fourth.pack()
entry = Entry(self, width=10, textvariable=x02)
entry.pack()
fifth = Label(self, text='Начальная координата y')
fifth.pack()
entry = Entry(self, width=10, textvariable=y02)
entry.pack()
first = Label(self, text='Данные для третьего графика')
first.pack()
second = Label(self, text='Начальная скорость')
second.pack()
entry = Entry(self, width=10, textvariable=v3)
entry.pack()
third = Label(self, text='Угол выстрела')
third.pack()
entry = Entry(self, width=10, textvariable=angle3)
entry.pack()
fourth = Label(self, text='Начальная координата x')
fourth.pack()
entry = Entry(self, width=10, textvariable=x03)
entry.pack()
fifth = Label(self, text='Начальная координата y')
fifth.pack()
entry = Entry(self, width=10, textvariable=y03)
entry.pack()
nonlocal v
nonlocal angle
nonlocal x0
nonlocal y0
nonlocal v2
nonlocal angle2
nonlocal x02
nonlocal y02
nonlocal v3
nonlocal angle3
nonlocal x03
nonlocal y03
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="Generate")
label.pack(pady=10, padx=10)
button1 = ttk.Button(self, text="Поменять значения",
command=lambda: controller.show_frame(StartPage))
button1.pack()
f = Figure(figsize=(5, 5), dpi=100)
a = f.add_subplot(111)
canvas = FigureCanvasTkAgg(f, 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)
t = ((2 * v * sin(angle)) / g)
vx = v * cos(angle)
t2 = ((2 * v2 * sin(angle2)) / g)
vx2 = v2 * cos(angle2)
t3 = ((2 * v3 * sin(angle3)) / g)
vx3 = v3 * cos(angle3)
dx = 0.01
xmin = x0
xmax = vx * t * cos(angle)
xmin2 = x02
xmax2 = vx2 * t2 * cos(angle2)
xmin3 = x03
xmax3 = vx3 * t3 * cos(angle3)
def func(x0, v, g, y0, angle):
y = x0 * tan(angle) - (1 / (2 * v ** 2)) * ((g * x0 ** 2) / (cos(angle) ** 2)) + y0
if y == 0:
return 0.0
return y
def func2(x02, v2, y02, angle2):
y2 = x02 * tan(angle2) - (1 / (2 * v2 ** 2)) * ((g * x02 ** 2) / (cos(angle2) ** 2)) + y02
if y2 == 0:
return 0.0
return y2
def func3(x03, v3, y03, angle3):
y3 = x03 * tan(angle3) - (1 / (2 * v3 ** 2)) * ((g * x03 ** 2) / (cos(angle3) ** 2)) + y03
if y3 == 0:
return 0.0
return y3
xlist = mlab.frange(xmin, xmax, dx)
xlist2 = mlab.frange(xmin2, xmax2, dx)
xlist3 = mlab.frange(xmin3, xmax3, dx)
ylist = [func(x0, v, g, y0, angle) for x0 in xlist]
ylist2 = [func2(x02, v2, y02, angle2) for x02 in xlist2]
ylist3 = [func3(x03, v3, y03, angle3) for x03 in xlist3]
pylab.plot(xlist, ylist)
pylab.plot(xlist2, ylist2)
pylab.plot(xlist3, ylist3)
pylab.show()
app = Fly()
app.mainloop()
I don’t know what part of the code to throw, so I threw off the whole.
I apologize to those who read this, but did not understand my problem. Please write what will be incomprehensible, I will try to give more information.
You could declare such variables in the scope of the module, i.e. at the top of your code put:
import matplotlib
from math import *
import pylab
from matplotlib import mlab
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure
import tkinter as tk
from tkinter import ttk
from tkinter import *
g = 9.81
v = IntVar()
angle = IntVar()
x0 = IntVar()
y0 = IntVar()
v2 = IntVar()
angle2 = IntVar()
x02 = IntVar()
y02 = IntVar()
v3 = IntVar()
angle3 = IntVar()
x03 = IntVar()
y03 = IntVar()
then rewrite StartPage
like this:
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="Начальная страница")
label.pack(pady=10, padx=10)
button = ttk.Button(self, text="Visit Page 1",
command=lambda: controller.show_frame(PageOne))
button.pack()
frame2 = Frame(self, borderwidth=4, relief=GROOVE)
frame2.pack()
first = Label(self, text='Данные для первого графика')
first.pack()
second = Label(self, text='Начальная скорость')
second.pack()
entry = Entry(self, width=10, textvariable=v)
entry.pack()
third = Label(self, text='Угол выстрела')
third.pack()
entry = Entry(self, width=10, textvariable=angle)
entry.pack()
fourth = Label(self, text='Начальная координата x')
fourth.pack()
entry = Entry(self, width=10, textvariable=x0)
entry.pack()
fifth = Label(self, text='Начальная координата y')
fifth.pack()
entry = Entry(self, width=10, textvariable=y0)
entry.pack()
frame3 = Frame(self, borderwidth=4, relief=GROOVE)
frame3.pack()
first = Label(self, text='Данные для второго графика')
first.pack()
second = Label(self, text='Начальная скорость')
second.pack()
entry = Entry(self, width=10, textvariable=v2)
entry.pack()
third = Label(self, text='Угол выстрела')
third.pack()
entry = Entry(self, width=10, textvariable=angle2)
entry.pack()
fourth = Label(self, text='Начальная координата x')
fourth.pack()
entry = Entry(self, width=10, textvariable=x02)
entry.pack()
fifth = Label(self, text='Начальная координата y')
fifth.pack()
entry = Entry(self, width=10, textvariable=y02)
entry.pack()
first = Label(self, text='Данные для третьего графика')
first.pack()
second = Label(self, text='Начальная скорость')
second.pack()
entry = Entry(self, width=10, textvariable=v3)
entry.pack()
third = Label(self, text='Угол выстрела')
third.pack()
entry = Entry(self, width=10, textvariable=angle3)
entry.pack()
fourth = Label(self, text='Начальная координата x')
fourth.pack()
entry = Entry(self, width=10, textvariable=x03)
entry.pack()
fifth = Label(self, text='Начальная координата y')
fifth.pack()
entry = Entry(self, width=10, textvariable=y03)
entry.pack()
As another (maybe nicer?) alternative, you might consider using a shared object to store the data, and give both frames a reference to that object, for example:
import matplotlib
from math import *
import pylab
from matplotlib import mlab
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure
import tkinter as tk
from tkinter import ttk
from tkinter import *
g = 9.81
class MyData():
v = IntVar()
angle = IntVar()
x0 = IntVar()
y0 = IntVar()
v2 = IntVar()
angle2 = IntVar()
x02 = IntVar()
y02 = IntVar()
v3 = IntVar()
angle3 = IntVar()
x03 = IntVar()
y03 = IntVar()
class Fly(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
tk.Tk.wm_title(self, "Fly")
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 = {}
data = MyData
for F in (StartPage, PageOne):
frame = F(container, self, data)
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(tk.Frame):
def __init__(self, parent, controller, data):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="Начальная страница")
label.pack(pady=10, padx=10)
button = ttk.Button(self, text="Visit Page 1",
command=lambda: controller.show_frame(PageOne))
button.pack()
frame2 = Frame(self, borderwidth=4, relief=GROOVE)
frame2.pack()
first = Label(self, text='Данные для первого графика')
first.pack()
second = Label(self, text='Начальная скорость')
second.pack()
entry = Entry(self, width=10, textvariable=data.v)
entry.pack()
third = Label(self, text='Угол выстрела')
third.pack()
entry = Entry(self, width=10, textvariable=data.angle)
entry.pack()
fourth = Label(self, text='Начальная координата x')
fourth.pack()
entry = Entry(self, width=10, textvariable=data.x0)
entry.pack()
fifth = Label(self, text='Начальная координата y')
fifth.pack()
entry = Entry(self, width=10, textvariable=data.y0)
entry.pack()
frame3 = Frame(self, borderwidth=4, relief=GROOVE)
frame3.pack()
first = Label(self, text='Данные для второго графика')
first.pack()
second = Label(self, text='Начальная скорость')
second.pack()
entry = Entry(self, width=10, textvariable=data.v2)
entry.pack()
third = Label(self, text='Угол выстрела')
third.pack()
entry = Entry(self, width=10, textvariable=data.angle2)
entry.pack()
fourth = Label(self, text='Начальная координата x')
fourth.pack()
entry = Entry(self, width=10, textvariable=data.x02)
entry.pack()
fifth = Label(self, text='Начальная координата y')
fifth.pack()
entry = Entry(self, width=10, textvariable=data.y02)
entry.pack()
first = Label(self, text='Данные для третьего графика')
first.pack()
second = Label(self, text='Начальная скорость')
second.pack()
entry = Entry(self, width=10, textvariable=data.v3)
entry.pack()
third = Label(self, text='Угол выстрела')
third.pack()
entry = Entry(self, width=10, textvariable=data.angle3)
entry.pack()
fourth = Label(self, text='Начальная координата x')
fourth.pack()
entry = Entry(self, width=10, textvariable=data.x03)
entry.pack()
fifth = Label(self, text='Начальная координата y')
fifth.pack()
entry = Entry(self, width=10, textvariable=data.y03)
entry.pack()
class PageOne(tk.Frame):
def __init__(self, parent, controller, data):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="Generate")
label.pack(pady=10, padx=10)
button1 = ttk.Button(self, text="Поменять значения",
command=lambda: controller.show_frame(StartPage))
button1.pack()
f = Figure(figsize=(5, 5), dpi=100)
a = f.add_subplot(111)
canvas = FigureCanvasTkAgg(f, 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)
t = ((2 * v * sin(data.angle)) / g)
vx = data.v * cos(data.angle)
t2 = ((2 * data.v2 * sin(data.angle2)) / g)
vx2 = data.v2 * cos(data.angle2)
t3 = ((2 * data.v3 * sin(data.angle3)) / g)
vx3 = data.v3 * cos(data.angle3)
dx = 0.01
xmin = data.x0
xmax = vx * t * cos(data.angle)
xmin2 = data.x02
xmax2 = vx2 * t2 * cos(data.angle2)
xmin3 = data.x03
xmax3 = vx3 * t3 * cos(data.angle3)
def func(x0, v, g, y0, angle):
y = x0 * tan(angle) - (1 / (2 * v ** 2)) * ((g * x0 ** 2) / (cos(angle) ** 2)) + y0
if y == 0:
return 0.0
return y
def func2(x02, v2, y02, angle2):
y2 = x02 * tan(angle2) - (1 / (2 * v2 ** 2)) * ((g * x02 ** 2) / (cos(angle2) ** 2)) + y02
if y2 == 0:
return 0.0
return y2
def func3(x03, v3, y03, angle3):
y3 = x03 * tan(angle3) - (1 / (2 * v3 ** 2)) * ((g * x03 ** 2) / (cos(angle3) ** 2)) + y03
if y3 == 0:
return 0.0
return y3
xlist = mlab.frange(xmin, xmax, dx)
xlist2 = mlab.frange(xmin2, xmax2, dx)
xlist3 = mlab.frange(xmin3, xmax3, dx)
ylist = [func(x0, data.v, g, data.y0, data.angle) for x0 in xlist]
ylist2 = [func2(x02, data.v2, data.y02, data.angle2) for x02 in xlist2]
ylist3 = [func3(x03, data.v3, data.y03, data.angle3) for x03 in xlist3]
pylab.plot(xlist, ylist)
pylab.plot(xlist2, ylist2)
pylab.plot(xlist3, ylist3)
pylab.show()
app = Fly()
app.mainloop()
There are other errors too, but this works around your scoping issue.