I want to Change the Position of a spinbox and an entry field by clicking on a button.
Clicking on the button Triggers this error:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python27\lib\lib-tk\Tkinter.py", line 1470, in __call__
return self.func(*args)
File "GUI.py", line 79, in changesite
if (site==0):
NameError: global name 'site' is not defined
My code is this here:
else:
w = Spinbox(dialog, from_=5, to=getmodulo(ceiling), increment = 5.0, state='readonly',font = "bold")
e = Entry(dialog,font = "bold")
e.place(x=390,y=120)
w.place(x=20,y=120)
site = 0
def changesite():
global site
if (site==0):
e.destroy()
w.destroy()
ws = Spinbox(dialog, from_=5, to=getmodulo(ceiling), increment = 5.0, state='readonly',font = "bold")
es = Entry(dialog,font = "bold")
es.place(x=20,y=120)
ws.place(x=390,y=120)
site = 1
if (site ==1):
ws.destroy()
es.destroy()
w = Spinbox(dialog, from_=5, to=getmodulo(ceiling), increment = 5.0, state='readonly',font = "bold")
e = Entry(dialog,font = "bold")
e.place(x=390,y=120)
w.place(x=20,y=120)
site = 0
As you see I use global for site, so how can I fix this error? I don't know how to do at the Moment.
All the best;
This is sort of a wild guess, since you do not show us all of your code, but I could reproduce the problem when the "global" variable is not really global, but defined in an enclosing function.
Minimal example:
# global f is expected here...
def foo():
f = 42 # ... but defined here
def bar():
global f
f = f + 1 # this causes a NameError
bar()
foo()
Instead, you could make site a member of the class (if any), or even of the outer method (like name_of_outer_method.site), or make it truly global, or use a modifyable wrapper type.
Related
This question already has an answer here:
TypeError: 'NoneType' object is not callable with tkinter
(1 answer)
Closed 1 year ago.
I'm trying to make a program that you can add infinite rooms to, so all of my code is built around using one variable to deduce which room is which. However when I run it, it gives me an error that doesn't directly reference any one line in my code, and since I'm a pretty new programmer, I don't know what it means. Also my code is pretty all over the place and incomplete. Thanks for any help!
The error
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\SCA0023\AppData\Local\Programs\Python\Python38\lib\tkinter\__init__.py", line 1892, in __call__
return self.func(*args)
TypeError: 'NoneType' object is not callable
The Code
from tkinter import *
root = Tk()
class Room:
def __init__(self, items):
self.objects = []
self.objects.append(items)
def list(self):
print(self.objects)
def addkitchenmenu(r): #add a new option menu attributed to a new room
globals()[f'kitchenvar_{r}'] = StringVar(root)
globals()[f'kitchenvar_{r}'].set("Add an appliance")
globals()[f'kitchenvar_{r}'].trace('w', applianceadd(r))
kitchenitems = ['Kettle', 'Toaster']
globals()[f'appliancelist_{r}'] = OptionMenu(root, globals()[f'kitchenvar_{r}'], *kitchenitems).pack()
addkitchen(r)
def applianceadd(r): #add a new room
globals()[f'kobjects_{r}'] = []
globals()[f'kobjects_{r}'].append(globals()[f'kitchenvar_{r}'].get())
items = globals()[f'kobjects_{r}']
globals()[f'kroom_{r}'] = Room(items)
globals()[f'kroom_{r}'].list()
def addkitchen(r): #add an appliance
globals()[f'addappliace{r}'] = Button(root, text='add appliance', command=lambda: applianceadd(r))
def newkitchencheck(): #find the next name for a room that isn't taken
varnotfound = True
a = 0
while varnotfound:
if f'kroom{a}' in globals():
a += 1
else:
r = a
varnotfound = False
addkitchenmenu(r)
addroombutton = Button(root, text="add kitchen", command=newkitchencheck)
addroombutton.pack()
root.mainloop()
You are passing result of applianceadd(r) (which is None) to .trace(). Change to .trace("w", lambda *_: applianceaddr(r)).
I want to make the program that I made can run
i make code like this
def cafe_food(self):
friedrice_items = tk.Entry(F_FItems)
friedrice_items.config(width=7, borderwidth=4, relief="sunken", font=("calibri", 10,"bold"),foreground="white", background="#248aa2")
friedrice_items.place(x=81, y=1)
def Total_Biil(self):
friedrice_price = 10
pizza_price = 20
if friedrice_items.get() != "":
friedrice_cost = friedrice_price * int(friedrice_items.get())
else:
friedrice_cost = 0
if pizza_items.get() != "":
friedrice_cost = pizza_price * int(pizza_items.get())
else:
pizza_cost = 0
total_bills = friedrice_cost + pizza_cost
if i run this code and..
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\kisah tegar\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 1885, in __call__
return self.func(*args)
File "D:\Code\Python\Project\restaurant_mg\main.py", line 498, in Total_Bill
if friedrice_items.get() != "":
NameError: name 'friedrice_items' is not defined
[Finished in 6.3s]
this my problem:(
how can i get friedrice_items in that function
If this piece of code is in a class, try adding self. before you variable names:
def cafe_food(self):
self.friedrice_items = tk.Entry(F_FItems)
self.friedrice_items.config(width=7, borderwidth=4, relief="sunken", font=("calibri", 10,"bold"),foreground="white", background="#248aa2")
self.friedrice_items.place(x=81, y=1)
def Total_Biil(self):
self.friedrice_price = 10
self.pizza_price = 20
if self.friedrice_items.get() != "":
self.friedrice_cost = self.friedrice_price * int(self.friedrice_items.get())
else:
self.friedrice_cost = 0
if self.pizza_items.get() != "":
self.friedrice_cost = self.pizza_price * int(self.pizza_items.get())
else:
self.pizza_cost = 0
self.total_bills = self.friedrice_cost + self.pizza_cost
self or whatever you name it, is a global keyword, where in a class, you can access the variable anywhere inside the class.
If you don't use self you would not be able to access it anywhere, like what happened to you before.
It says that base_obj is not defined. But I did define it already. So why am I getting this error?
here is the code:
from tkinter import *
root = Tk()
class BaseClass:
def __init__(self,an_int,a_string):
self.the_int = an_int
self.the_string = a_string
class BiggerClass:
def __init__(self,an_instance_of_BaseClass,big_class_string,big_class_int,new_name):
self.the_instance_of_BaseClass = an_instance_of_BaseClass #here we are aggregating the base class into the bigger class
self.the_big_class_string = big_class_string
self.the_big_class_int = big_class_int
self.the_big_class_new_name = new_name
base_int_var = IntVar()
base_string_var = StringVar()
bigger_name_var = StringVar()
entry_base_int = Entry(root,textvariable = base_int_var).pack()
entry_base_string = Entry(root,textvariable = base_string_var).pack()
big_new_name_var = StringVar()
entry_bigger_name = Entry(root, textvariable = bigger_name_var).pack()
entry_big_new_name = Entry(root,textvariable = big_new_name_var).pack()
def create_base_class_instance():
global base_obj
base_obj = BaseClass(base_int_var.get(),base_string_var.get()) # I define 'base_obj' here
list_of_bigs = []
def create_bigger_class_instance(big_handle):
bigger_name_var = big_handle
big_handle = BiggerClass(base_obj,bigger_name_var.get(),55,big_new_name_var.get())
list_of_bigs.append(big_handle)
#global big_obj
#big_obj = BiggerClass(base_obj,bigger_name_var.get(),45)
create_base_class_button = Button(root, text ="create base class", command = create_base_class_instance).pack()
create_big_class_button = Button(root, text ="create big class", command = create_bigger_class_instance(big_new_name_var)).pack()
match_name_var = StringVar()
entry_match_name = Entry(root,textvariable = match_name_var).pack()
def my_button_method():
for a_big in list_of_bigs:
if a_big.the_big_class_new_name == match_name_var:
print(a_big.the_instance_of_BaseClass.the_string)
#print(big_obj.the_instance_of_BaseClass.the_int)
#bigger_class_obj = BiggerClass(base_obj,"hello this is the big class",45)
button_print_out = Button(root,text = "press me", command = my_button_method).pack()
root.mainloop()
here is the error message:
Traceback (most recent call last):
File "C:/Users/TOTTY/PycharmProjects/my game/aggregation practice fork 1.py", line 45, in <module>
create_big_class_button = Button(root, text ="create big class", command = create_bigger_class_instance(big_new_name_var)).pack()
File "C:/Users/TOTTY/PycharmProjects/my game/aggregation practice fork 1.py", line 39, in create_bigger_class_instance
big_handle = BiggerClass(base_obj,bigger_name_var.get(),55,big_new_name_var.get())
NameError: name 'base_obj' is not defined
You have defined the object in create_base_class_instance function and you are calling it in my_button_method.
You should initialize it outside, and use global keyword in both functions.
However using global variables considered code smell. I would advise finding another solution, for example passing base_obj as an argument to both functions.
base_obj = None
def some_function():
global base_obj
# some code referencing base_obj
def other_function():
global base_obj
# some code referencing base_obj
Functions in Python are executed only when they are called. The keyword global is used to indicate that the variable used here is the same as in the global scope. Thus you will need to add a declaring statement in the main class and not in any of the sub function.
For e.g. You will have to write
base_obj = None
In the main class before either of the two functions is called. You do not need global base_obj in your second function as you are not assigning any value to it.
Look at this line of code:
create_big_class_button = Button(..., command = create_bigger_class_instance(big_new_name_var)).pack()
You are immediately calling create_bigger_class_instance(...), and the result of that is getting assigned to the command. Since create_bigger_class_instance relies on the existence of base_obj, and you haven't created base_obj yet since it's tied to a button click, you get the error.
(As a side note, doing something like create_big_class_button = Button(...).pack() will always result in create_big_class_button being set to None, because that is what pack() returns.)
I am doing a test writing a script that validate a spinbox to implement it on a larger system, but I am struggling with python because it is warning that there is no spinbox attribute on my Window class. Check my code:
from Tkinter import *
class Window:
def __init__(self, toplevel):
self.spinbox = Spinbox(toplevel, from_ = 0, to = 10,
validate = 'all', validatecommand = self.validate)
self.spinbox.pack()
def validate(self):
print self.spinbox.get()
root = Tk()
Window(root)
root.mainloop()
This is the error it is giving:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python27\lib\lib-tk\Tkinter.py", line 1486, in __call__
return self.func(*args)
File "D:\DOCS\FILIPE\PROGRAMMING\PYTHON\Tkinter sandbox\01 - spinbox validate.
py", line 13, in validate
print self.spinbox.get()
AttributeError: Window instance has no attribute 'spinbox'
Anyone could help me with this one?
If you add some print statements to your code:
class Window:
def __init__(self, toplevel):
print "A start", self, self.__dict__
self.spinbox = Spinbox(toplevel, from_ = 0, to = 10,
validate = 'all', validatecommand = self.validate)
self.spinbox.pack()
print "A end", self, self.__dict__
def validate(self):
print "B", self, self.__dict__
print self.spinbox.get()
#...
You get the output:
A start <__main__.Window instance at 0x7fe4f8deec20> {}
B <__main__.Window instance at 0x7fe4f8deec20> {}
Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1532, in __call__
return self.func(*args)
File "t.py", line 14, in validate
print self.spinbox.get()
AttributeError: Window instance has no attribute 'spinbox'
A end <__main__.Window instance at 0x7fe4f8deec20> {'spinbox': <Tkinter.Spinbox instance at 0x7fe4f8e0da28>}
This means that the validate function is called inside the constructor to validate the initial value, and at that point self.spinbox has not yet been set. You will need to either check if you are still constructing or delay setting validatecommand like this:
self.spinbox = Spinbox(toplevel, from_ = 0, to = 10,
validate = 'all')
self.spinbox["validatecommand"] = self.validate
self.spinbox.pack()
I MANAGED TO SOLVE THE PROBLEM USING TEXTVARIABLES AND THE TRACE METHOD
#Validates
self.countstringvar = StringVar()
self.countstringvar.trace("w", lambda name, index, mode,
sv = self.countstringvar: self.noLettersValidate(sv, self.count))
self.starsstringvar = StringVar()
self.starsstringvar.trace("w", lambda name, index, mode,
sv = self.starsstringvar: self.noLettersValidate(sv, self.stars))
self.scorestringvar = StringVar()
self.scorestringvar.trace("w", lambda name, index, mode,
sv = self.scorestringvar: self.noLettersValidate(sv, self.score))
self.count['textvariable'] = self.countstringvar
self.stars['textvariable'] = self.starsstringvar
self.score['textvariable'] = self.scorestringvar
def removeLetters(self, s):
a = []
for i in s:
if i.isdigit():
a.append(i)
return ''.join(a)
def noLettersValidate(self, sv, w):
w.text(self.removeLetters(sv.get()))
Thanks for everyone contributions!
from tkinter import *
import math
def calculate(x):
while x**2+math.sqrt(x) < 4:
x = x+0.000001
print(x)
gui = Tk()
gui.geometry("300x150")
button = Button(gui, text="Udregn", command=calculate).pack()
gui.mainloop()
I try to use this code and hit the button to make it calculate, however it gives me this error once I press the button instead:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python34\lib\tkinter\__init__.py", line 1487, in __call__
return self.func(*args)
TypeError: udregn() missing 1 required positional argument: 'x'
Button callbacks are not called with any arguments, which makes sense, because the only information a button provides is that it has been clicked. You'll have to define the function like this:
def calculate():
...
and think about another approach for how to get a value of x for inside the function. Typically, it will come from another GUI component, which you can either access as a global value, or you can have calculate be a bound method of an object that encapsulates x.
class XContainer(object):
def __init__(self, x):
self.x = x
def calculate(self):
while self.x**2+math.sqrt(self.x) < 4:
self.x += 0.000001
print(self.x)
x = XContainer(5)
button = Button(gui, text="Udregn", command=x.calculate)
button.pack()
In this case, some other code will be responsible for creating and possibly modifying x.