SyntaxError: name 'v' is used prior to nonlocal declaration
Question:
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.
Answers:
As the error suggests, it’s your nonlocal declarations. I’ve switched them to globals and called them in the appropriate order. Your code will still not run as you have some type issues later on, but that is out of the scope of the question
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()
global v
v = IntVar()
global angle
angle = IntVar()
global x0
x0 = IntVar()
global y0
y0 = IntVar()
global v2
v2 = IntVar()
global angle2
angle2 = IntVar()
global x02
x02 = IntVar()
global y02
y02 = IntVar()
global v3
v3 = IntVar()
global angle3
angle3 = IntVar()
global x03
x03 = IntVar()
global y03
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()
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()
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.
I got the same error below:
SyntaxError: name ‘x’ is used prior to nonlocal declaration
When trying to use the local and non-local variables x
in inner() as shown below:
x = 0
def outer():
x = 5
def inner():
x = 10 # Local variable
x += 1
print(x)
nonlocal x # Non-local variable
x += 1
print(x)
inner()
outer()
And, when trying to use the global and non-local variables x
in inner() as shown below:
x = 0
def outer():
x = 5
def inner():
global x # Global variable
x += 1
print(x)
nonlocal x # Non-local variable
x += 1
print(x)
inner()
outer()
So, I renamed x
to y
for the local variable as shown below:
x = 0
def outer():
y = 5 # Here
def inner():
x = 10
x += 1
print(x)
nonlocal y # Here
y += 1
print(y)
inner()
outer()
Then, the error was solved as shown below:
11
6
And, I renamedx
to y
for the non-local variable as shown below:
x = 0
def outer():
y = 5 # Here
def inner():
global x
x += 1
print(x)
nonlocal y # Here
y += 1 # Here
print(y) # Here
inner()
outer()
Then, the error was solved as shown below:
1
6
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.
As the error suggests, it’s your nonlocal declarations. I’ve switched them to globals and called them in the appropriate order. Your code will still not run as you have some type issues later on, but that is out of the scope of the question
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()
global v
v = IntVar()
global angle
angle = IntVar()
global x0
x0 = IntVar()
global y0
y0 = IntVar()
global v2
v2 = IntVar()
global angle2
angle2 = IntVar()
global x02
x02 = IntVar()
global y02
y02 = IntVar()
global v3
v3 = IntVar()
global angle3
angle3 = IntVar()
global x03
x03 = IntVar()
global y03
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()
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()
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.
I got the same error below:
SyntaxError: name ‘x’ is used prior to nonlocal declaration
When trying to use the local and non-local variables x
in inner() as shown below:
x = 0
def outer():
x = 5
def inner():
x = 10 # Local variable
x += 1
print(x)
nonlocal x # Non-local variable
x += 1
print(x)
inner()
outer()
And, when trying to use the global and non-local variables x
in inner() as shown below:
x = 0
def outer():
x = 5
def inner():
global x # Global variable
x += 1
print(x)
nonlocal x # Non-local variable
x += 1
print(x)
inner()
outer()
So, I renamed x
to y
for the local variable as shown below:
x = 0
def outer():
y = 5 # Here
def inner():
x = 10
x += 1
print(x)
nonlocal y # Here
y += 1
print(y)
inner()
outer()
Then, the error was solved as shown below:
11
6
And, I renamedx
to y
for the non-local variable as shown below:
x = 0
def outer():
y = 5 # Here
def inner():
global x
x += 1
print(x)
nonlocal y # Here
y += 1 # Here
print(y) # Here
inner()
outer()
Then, the error was solved as shown below:
1
6