Tkinter – "Label" object is not callable ; NOT a case of naming an object after LABEL class
Question:
I’m working on a tkinter GUI API-based application.
I’m attempting to modularize my code in which each function has a specific task to do and some functions just call other functions.
In my case, I bind the search
button to the function, search
, whose job is to call other API-based functions, such as full_name
.
When I did this, an error is thrown, saying that in search full_name() TypeError: 'Label' object is not callable
what’s interesting is that
- I see no mention of creating instances of Label classes in
full_name()
- when I bind the
search
button to function, full_name()
, it works just fine. However, I want to bind it to a function that will call all API-based functions, and so far, it’s not working
Here’s the code below:
#MER for frames placement through .Grid()
#import necessary modules
from tkinter import *
from tkinter import ttk
from PIL import ImageTk, Image
from tkinter import messagebox
import requests
import json
root = Tk()
root.title("F1 Desktop Application")
root.geometry("500x600")
root.configure(bg="white")
#generate 2022 drivers-list [can scale to drivers-list by changing the]
drivers_list_request = requests.get("http://ergast.com/api/f1/2022/drivers.json")
#initialize empty-list
drivers_list = []
drivers_list_object = json.loads(drivers_list_request.content)
for elements in drivers_list_object["MRData"]["DriverTable"]["Drivers"]:
drivers_list.append(elements["givenName"] + " " + elements["familyName"])
#NEED TO UNDERSTAND PRECEDENCE BETWEEN WIDTH, HEIGHT SETTING, VS SPANS. STICKY MAKES PERFECT SENSE
top_frame = LabelFrame(root, width = 300, height = 125)
top_frame.grid(row = 0, column = 0, columnspan = 2)
top_frame.rowconfigure(0, minsize = 75)
top_frame.columnconfigure(0, minsize = 300)
# Update the Entry widget with the selected item in list
def check(e):
v= entry_box.get()
if v=='':
hide_button(menu)
else:
data=[]
for item in drivers_list:
if v.lower() in item.lower():
data.append(item)
update(data)
show_button(menu)
def update(data):
# Clear the Combobox
menu.delete(0, END)
# Add values to the combobox
for value in data:
menu.insert(END,value)
def fillout(event):
try:
entry_box.delete(0,END)
entry_box.insert(0,menu.get(menu.curselection()))
hide_button(menu)
#handle a complete deletion of entry-box via cursor double tap
except:
pass
def hide_button(widget):
widget.grid_remove()
def show_button(widget):
widget.grid()
def full_name():
user_input = entry_box.get()
lower_user_input = user_input.lower().split(" ")[1]
response = requests.get("http://ergast.com/api/f1/drivers/{}.json".format(lower_user_input))
print(response.status_code)
response_object = json.loads(response.content)
name = response_object["MRData"]["DriverTable"]["Drivers"][0]["givenName"] + " " + response_object["MRData"]["DriverTable"]["Drivers"][0]["familyName"]
print(name)
def search():
full_name()
#once works, then make API request
header_label = Label(top_frame, text = "F1 2022 Drivers App", font = ("Arial bold",14), bg = "white")
header_label.grid(row = 0, column = 0, padx = 30)
search_button = Button(top_frame, text = "search" , command = search)
search_button.grid(row = 1, column = 1)
entry_box= Entry(top_frame)
entry_box.grid(row = 1, column = 0)
entry_box.bind('<KeyRelease>',check)
menu= Listbox(top_frame, height = 4)
menu.grid(row = 2, column = 0)
menu.bind("<<ListboxSelect>>",fillout)
left_frame = LabelFrame(root, width = 250, height = 225, borderwidth = 0, highlightthickness = 2)
left_frame.grid(row = 1, column = 0, sticky = NW, padx = 10, pady = 15)
#left_frame.grid_propagate(False)
left_frame.rowconfigure(0, minsize = 100)
left_frame.columnconfigure(0, minsize = 200)
#left_frame_content = LabelFrame(, width = 125, height = 70)
#left_frame_content.grid(row = 1, column = 1, sticky = W)
basic_info = Label(left_frame, text = "Basic Info ", font = ("Arial bold",14))
basic_info.grid(row = 0, column = 0)
full_name = Label(left_frame, text = "Full Name :")
full_name.grid(row = 1, column = 0, sticky = W)
driver_code = Label(left_frame, text = "Driver Code : ")
driver_code.grid(row = 2, column = 0, sticky = W)
nationality = Label(left_frame, text = "Nationality : ")
nationality.grid(row = 3, column = 0, sticky = W)
bottom_left_frame = LabelFrame(root, width = 250, height = 225)
bottom_left_frame.grid(row = 2, column = 0, sticky = N, padx = 10)
bottom_left_frame.rowconfigure(0, minsize = 50)
bottom_left_frame.columnconfigure(0, minsize = 200)
F1_career = Label(bottom_left_frame, text = "F1 Career ", font = ("Arial bold",14))
F1_career.grid(row = 0, column = 0)
wins = Label(bottom_left_frame, text = "Wins :")
wins.grid(row = 1, column = 0, sticky = W)
wins.configure(text = "Wins :" + " 7")
poles = Label(bottom_left_frame, text = "Poles :")
poles.grid(row = 2, column = 0, sticky = W)
test = Label(bottom_left_frame, text = "test")
test.grid(row = 2, column = 1)
podiums = Label(bottom_left_frame, text = "Podiums :")
podiums.grid(row = 3, column = 0, sticky = W)
podiums.configure(text = "Podiums :" + "Lewis Hamilton")
drivers_championships = Label(bottom_left_frame, text = "Championships :")
drivers_championships.grid(row = 4, column = 0, sticky = W)
bottom_right_frame = LabelFrame(root, width = 250, height = 225)
bottom_right_frame.grid(row = 2, column = 1, sticky = W)
bottom_right_frame.rowconfigure(0, minsize = 50)
bottom_right_frame.columnconfigure(0, minsize = 150)
hide_button(menu)
root.mainloop()
Feel free to ask for more clarity. I would be grateful if anyone has a reason/solution
Answers:
You have used the same name for a label:
full_name = Label(left_frame, text = "Full Name :")
So it will override the full_name()
.
Use another name for the label, for example full_name_label
:
full_name_label = Label(left_frame, text = "Full Name :")
full_name_label.grid(row = 1, column = 0, sticky = W)
I’m working on a tkinter GUI API-based application.
I’m attempting to modularize my code in which each function has a specific task to do and some functions just call other functions.
In my case, I bind the search
button to the function, search
, whose job is to call other API-based functions, such as full_name
.
When I did this, an error is thrown, saying that in search full_name() TypeError: 'Label' object is not callable
what’s interesting is that
- I see no mention of creating instances of Label classes in
full_name()
- when I bind the
search
button to function,full_name()
, it works just fine. However, I want to bind it to a function that will call all API-based functions, and so far, it’s not working
Here’s the code below:
#MER for frames placement through .Grid()
#import necessary modules
from tkinter import *
from tkinter import ttk
from PIL import ImageTk, Image
from tkinter import messagebox
import requests
import json
root = Tk()
root.title("F1 Desktop Application")
root.geometry("500x600")
root.configure(bg="white")
#generate 2022 drivers-list [can scale to drivers-list by changing the]
drivers_list_request = requests.get("http://ergast.com/api/f1/2022/drivers.json")
#initialize empty-list
drivers_list = []
drivers_list_object = json.loads(drivers_list_request.content)
for elements in drivers_list_object["MRData"]["DriverTable"]["Drivers"]:
drivers_list.append(elements["givenName"] + " " + elements["familyName"])
#NEED TO UNDERSTAND PRECEDENCE BETWEEN WIDTH, HEIGHT SETTING, VS SPANS. STICKY MAKES PERFECT SENSE
top_frame = LabelFrame(root, width = 300, height = 125)
top_frame.grid(row = 0, column = 0, columnspan = 2)
top_frame.rowconfigure(0, minsize = 75)
top_frame.columnconfigure(0, minsize = 300)
# Update the Entry widget with the selected item in list
def check(e):
v= entry_box.get()
if v=='':
hide_button(menu)
else:
data=[]
for item in drivers_list:
if v.lower() in item.lower():
data.append(item)
update(data)
show_button(menu)
def update(data):
# Clear the Combobox
menu.delete(0, END)
# Add values to the combobox
for value in data:
menu.insert(END,value)
def fillout(event):
try:
entry_box.delete(0,END)
entry_box.insert(0,menu.get(menu.curselection()))
hide_button(menu)
#handle a complete deletion of entry-box via cursor double tap
except:
pass
def hide_button(widget):
widget.grid_remove()
def show_button(widget):
widget.grid()
def full_name():
user_input = entry_box.get()
lower_user_input = user_input.lower().split(" ")[1]
response = requests.get("http://ergast.com/api/f1/drivers/{}.json".format(lower_user_input))
print(response.status_code)
response_object = json.loads(response.content)
name = response_object["MRData"]["DriverTable"]["Drivers"][0]["givenName"] + " " + response_object["MRData"]["DriverTable"]["Drivers"][0]["familyName"]
print(name)
def search():
full_name()
#once works, then make API request
header_label = Label(top_frame, text = "F1 2022 Drivers App", font = ("Arial bold",14), bg = "white")
header_label.grid(row = 0, column = 0, padx = 30)
search_button = Button(top_frame, text = "search" , command = search)
search_button.grid(row = 1, column = 1)
entry_box= Entry(top_frame)
entry_box.grid(row = 1, column = 0)
entry_box.bind('<KeyRelease>',check)
menu= Listbox(top_frame, height = 4)
menu.grid(row = 2, column = 0)
menu.bind("<<ListboxSelect>>",fillout)
left_frame = LabelFrame(root, width = 250, height = 225, borderwidth = 0, highlightthickness = 2)
left_frame.grid(row = 1, column = 0, sticky = NW, padx = 10, pady = 15)
#left_frame.grid_propagate(False)
left_frame.rowconfigure(0, minsize = 100)
left_frame.columnconfigure(0, minsize = 200)
#left_frame_content = LabelFrame(, width = 125, height = 70)
#left_frame_content.grid(row = 1, column = 1, sticky = W)
basic_info = Label(left_frame, text = "Basic Info ", font = ("Arial bold",14))
basic_info.grid(row = 0, column = 0)
full_name = Label(left_frame, text = "Full Name :")
full_name.grid(row = 1, column = 0, sticky = W)
driver_code = Label(left_frame, text = "Driver Code : ")
driver_code.grid(row = 2, column = 0, sticky = W)
nationality = Label(left_frame, text = "Nationality : ")
nationality.grid(row = 3, column = 0, sticky = W)
bottom_left_frame = LabelFrame(root, width = 250, height = 225)
bottom_left_frame.grid(row = 2, column = 0, sticky = N, padx = 10)
bottom_left_frame.rowconfigure(0, minsize = 50)
bottom_left_frame.columnconfigure(0, minsize = 200)
F1_career = Label(bottom_left_frame, text = "F1 Career ", font = ("Arial bold",14))
F1_career.grid(row = 0, column = 0)
wins = Label(bottom_left_frame, text = "Wins :")
wins.grid(row = 1, column = 0, sticky = W)
wins.configure(text = "Wins :" + " 7")
poles = Label(bottom_left_frame, text = "Poles :")
poles.grid(row = 2, column = 0, sticky = W)
test = Label(bottom_left_frame, text = "test")
test.grid(row = 2, column = 1)
podiums = Label(bottom_left_frame, text = "Podiums :")
podiums.grid(row = 3, column = 0, sticky = W)
podiums.configure(text = "Podiums :" + "Lewis Hamilton")
drivers_championships = Label(bottom_left_frame, text = "Championships :")
drivers_championships.grid(row = 4, column = 0, sticky = W)
bottom_right_frame = LabelFrame(root, width = 250, height = 225)
bottom_right_frame.grid(row = 2, column = 1, sticky = W)
bottom_right_frame.rowconfigure(0, minsize = 50)
bottom_right_frame.columnconfigure(0, minsize = 150)
hide_button(menu)
root.mainloop()
Feel free to ask for more clarity. I would be grateful if anyone has a reason/solution
You have used the same name for a label:
full_name = Label(left_frame, text = "Full Name :")
So it will override the full_name()
.
Use another name for the label, for example full_name_label
:
full_name_label = Label(left_frame, text = "Full Name :")
full_name_label.grid(row = 1, column = 0, sticky = W)