I'm trying to modify the complex_example.py from the CustomTkinter website/github so that I can get it to eventually modify some file parameters that are used in a feeding machine for fish.
When I run the code in PyCharm I get the window that I'm expecting (ignore the obvious size issues).
However, whenever I click on any button, such as the "Cancel" button I get the following error
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/tkinter/init.py", line 2345, in getattr return getattr(self.tk, attr)
AttributeError: '_tkinter.tkapp' object has no attribute 'sidebar_button_event'
Strange thing is that when I run the original complex_example.py there is no issue with the buttons.
I'm sure the issue is obvious, but I'm still learning Python and Google has not been my friend.
Any help would be greatly appreciated.
import sys
#import tkinter
#import tkinter.messagebox
import customtkinter
customtkinter.set_appearance_mode("System") # Modes: "System" (standard), "Dark", "Light"
customtkinter.set_default_color_theme("blue") # Themes: "blue" (standard), "green", "dark-blue"
class App(customtkinter.CTk):
current_speed = 0
current_direction = "Clockwise"
current_steps = 0
def __init__(self):
super().__init__()
# Begin row count
r=0
# Set column to 0
c=0
# Set speed entry
current_speed=0
# Set direction
current_direction=f"Clockwise"
# Set steps per feeding
current_steps_feeding=200
# configure window
self.title("Motor Options")
self.geometry(f"{750}x{385}")
# configure grid layout (4x4)
# self.grid_columnconfigure((0, 1, 2, 3), weight=1)
# self.grid_rowconfigure((0, 1, 2), weight=1)
# create sidebar frame with widgets
self.sidebar_frame = customtkinter.CTkFrame(self, width=750, corner_radius=0)
self.sidebar_frame.grid(row=0, column=c, rowspan=3, sticky="nsew")
# self.sidebar_frame.grid_rowconfigure(9, weight=1)
self.logo_label = customtkinter.CTkLabel(self.sidebar_frame, text="Motor Options", font=customtkinter.CTkFont(size=20, weight="bold"))
self.logo_label.grid(row=r, column=c, columnspan=4, padx=20, pady=(10,10))
r +=1
self.logo_label = customtkinter.CTkLabel(self.sidebar_frame, text="Speed", font=customtkinter.CTkFont(size=20, weight="bold"))
self.logo_label.grid(row=r, column=c, padx=20, pady=(10,10))
# Speed up
c +=1
self.sidebar_button_1 = customtkinter.CTkButton(self.sidebar_frame, command=lambda: self.sidebar_button_event(1))
self.sidebar_button_1.grid(row=r, column=c, padx=20, pady=(10,10))
# Speed down
c +=1
self.sidebar_button_2 = customtkinter.CTkButton(self.sidebar_frame, command=lambda: self.sidebar_button_event(2))
self.sidebar_button_2.grid(row=r, column=c, padx=20, pady=(10,10))
# create Speed entry box
c +=1
self.entry_speed = customtkinter.CTkEntry(self.sidebar_frame, placeholder_text=current_speed)
self.entry_speed.grid(row=r, column=c, padx=20, pady=(10,10))
# Cancel
r +=1
self.sidebar_button_16 = customtkinter.CTkButton(self.sidebar_frame, command=lambda: self.sidebar_button_event(16))
self.sidebar_button_16.grid(row=r, column=c, padx=20, pady=(10,10))
# set default values
self.sidebar_button_1.configure(text="Faster")
self.sidebar_button_2.configure(text="Slower")
self.sidebar_button_16.configure(text="Cancel")
def sidebar_button_event(buttonNum):
if buttonNum == 1:
print(f"Faster")
print(f"Attempt to increase speed beyond 100, speed set to 100")
elif buttonNum == 2:
print(f"Slower")
elif buttonNum == 16:
print(f"Cancel")
sys.exit(0)
if __name__ == "__main__":
app = App()
app.mainloop()
sidebar_button_event()
is a nested function inside __init__()
, not a class method, so it need to be called without prefix self.
:
command=lambda: sidebar_button_event(...)
Or change it to a class method:
class App(custometkinter.CTk):
...
def __init__(self):
...
# same indentation as `__init__()` and added `self` argument
def sidebar_button_event(self, buttonNum):
...