I am working on a project in Python with Pycharm as my code-editor. In my code I faced variable not defined error in spite of declaring it as Global. Here's the code snippet:
global hpw
global mil
def bt_cars(hpw, mil):
hpw = StringVar()
mil = StringVar()
w1 = Toplevel()
w1.title("Choose Features")
w1.geometry("430x200")
lb3 = Label(w1, text="Choose features for comparison", bg="yellow"
, font=('Arial Black', 18), width=25)
lb4 = Label(w1, text=" ", anchor=tk.CENTER)
fr1 = LabelFrame(w1, width=20, padx=100)
hp_cb = Checkbutton(fr1, text="Horsepower", variable=hp, anchor='w', onvalue="Horsepower", offvalue=" ")
hpw_cb.grid()
hpw_cb.deselect()
mil_cb = Checkbutton(fr1, text="Mileage", variable=mi, anchor='w', onvalue="Mileage", offvalue=" ")
mil_cb.grid()
mil_cb.deselect()
lb3.grid(row=0, column=1)
lb4.grid(row=1, column=1)
fr1.grid(row=2, column=1)
root.withdraw()
bt1 = Button(root, text="CARS", width=5, font=('Calibri', 15), command=bt_cars)
bt1.grid(row=7)
space2 = Label(root, text="\n\n")
space2.grid(row=6)
var_stor1 = [mil, hpw] #NameError here, python doesn't recognise mil and hpw
for i in var_stor1:
if i.get() != " ":
work_stor.append(i)
print(work_stor)
root.mainloop()
The error for this code:
C:\Users\bspoo\AppData\Local\Programs\Python\Python310-32\python.exe "E:/Software/Python /Programs/School/Project SPASC/SPASC II.py"
Traceback (most recent call last):
File "E:\Software\Python\Programs\School\Project SPASC\SPASC II.py", line 55, in <module>
var_stor1 = [mil, hpw]
NameError: name 'mil' is not defined. Did you mean: 'min'?
What should I do to overcome this error?
*NOTE: This is only part of my code. So please ignore if import tkinter is missing
CodePudding user response:
The simple answer is to get rid of the global
statements in the global scope and put them in bt_cars
instead:
# Get rid of these altogether
# global hpw
# global mil
def bt_cars(): # Button callbacks are not called with any arguments
global hpw, mil
# Are these the assignments you want?
hpw = StringVar()
mil = StringVar()
...
If you want to use hpw
and mil
in the global scope, you need to either define them before bt_cars
is called, or you need to ensure that bt_cars
is called before you try to use hpw
or mil
.
CodePudding user response:
In order to change the value of a global variable inside a function, you must declare it global inside the function.
You should check the file of ASCII .line 55
CodePudding user response:
You need to go back to fundamentals of functions and function parameters and the scope of variables in python. Please go through all the comments I have added in your code. Also, There is very little clarity about what you are trying to do here. I hope it will clarify things for you:
from tkinter import *
root = Tk()
# global hpw
# global mil
# Please initialize the variables with an argument for the function or directly use a value as an argument in yout function
# for example, no need of global keyword, following variables already have a global scope:
hpw = 'a'
mil = 'b'
# it isnt necessary for these variables to be named same as function parameter. The function parameters have a scope local to the function.
def bt_cars(hpw, mil):
# hpw and mil have a scope local to the function. Also I dont understand their use as in your function you havent used hpw and mil anywhere.
hp = StringVar() # Do you mean this hp is the hpw you intended
mi = StringVar() # Do you mean this mi is the mil you intended
w1 = Toplevel()
w1.title("Choose Features")
w1.geometry("430x200")
lb3 = Label(w1, text="Choose features for comparison",
bg="yellow", font=('Arial Black', 18), width=25)
lb4 = Label(w1, text=" ", anchor=CENTER)
fr1 = LabelFrame(w1, width=20, padx=100)
hp_cb = Checkbutton(fr1, text="Horsepower", variable=hp,
anchor='w', onvalue="Horsepower", offvalue=" ")
hp_cb.grid()
hp_cb.deselect()
mil_cb = Checkbutton(fr1, text="Mileage", variable=mi,
anchor='w', onvalue="Mileage", offvalue=" ")
mil_cb.grid()
mil_cb.deselect()
lb3.grid(row=0, column=1)
lb4.grid(row=1, column=1)
fr1.grid(row=2, column=1)
root.withdraw()
# The function arguments here?? You could use lambda here
bt1 = Button(root, text="CARS", width=5, font=('Calibri', 15), command=bt_cars)
bt1.grid(row=7)
space2 = Label(root, text="\n\n")
space2.grid(row=6)
var_stor1 = [hpw, mil] # There wont be any error now.