pythontkinterlabelconfigurecustomtkinter

The Python code label.configure is not being updated because it was added in a for-loop syntax


I'm having trouble updating and replacing the output text into customtkinter gui using label syntax. When I clicked the button, it was not being replaced with the new one. Below is my code.

import customtkinter
from PIL import Image

customtkinter.set_appearance_mode("dark")
customtkinter.set_default_color_theme("dark-blue")

root = customtkinter.CTk()

root.title("Movie Recoomendation")
root.geometry("700x700")

# Sample data: Dictionary with user preferences
user_preferences = {
    "Alice": ["Action", "Adventure", "Comedy"],
    "Bob": ["Drama", "Romance", "Thriller"],
    "Charlie": ["Comedy", "Horror"],
    "David": ["Action", "Comedy", "Sci-Fi"],
    "James": ["kdrama"]
}

# Sample data: Dictionary with movie ratings
movie_ratings = {
    "Rebel Moon": {"Action": 4, "Adventure": 3, "Comedy": 5, "Drama": 2, "Romance": 1, "Thriller": 3, "Horror": 2, "Sci-Fi": 4},
    "Magic Mike": {"Action": 3, "Adventure": 4, "Comedy": 2, "Drama": 5, "Romance": 3, "Thriller": 4, "Horror": 1, "Sci-Fi": 3},
    "Robo WOman": {"Action": 5, "Adventure": 3, "Comedy": 4, "Drama": 2, "Romance": 1, "Thriller": 3, "Horror": 2, "Sci-Fi": 4},
    "The family plan": {"Action": 2, "Adventure": 3, "Comedy": 5, "Drama": 4, "Romance": 2, "Thriller": 3, "Horror": 1, "Sci-Fi": 4},
    "The purge": {"Action": 4, "Adventure": 2, "Comedy": 3, "Drama": 5, "Romance": 1, "Thriller": 4, "Horror": 3, "Sci-Fi": 2},
    "My Girlfriend is a gumiho": {"Action": 5, "kdrama": 5, "Comedy": 5, "Drama": 5, "Romance": 1, "Thriller": 4, "Horror": 3, "Sci-Fi": 2},
    "Gung Family Book": {"Action": 5, "kdrama": 5, "Comedy": 5, "Drama": 5, "Romance": 1, "Thriller": 4, "Horror": 3, "Sci-Fi": 2},
    "I am robot": {"Action": 5, "kdrama": 5, "Comedy": 5, "Drama": 5, "Romance": 1, "Thriller": 4, "Horror": 3, "Sci-Fi": 2}
}

    
# Function to recommend movies based on user preferences
def recommend_movies(user):
    preferences = user_preferences.get(user, [])
    if not preferences:
        return "User not found or preferences not available."

    movie_scores = {}
    for movie, ratings in movie_ratings.items():
        score = sum(ratings[genre] for genre in preferences if genre in ratings)
        movie_scores[movie] = score
    
    sorted_movies = sorted(movie_scores.items(), key=lambda x: x[1], reverse=True)
    top_recommendations = [movie for movie, _ in sorted_movies[:3]]
    return top_recommendations

#top 5
def recommend_movies_top5(user):
    preferences = user_preferences.get(user, [])
    if not preferences:
        return "User not found or preferences not available."

    movie_scores = {}
    for movie, ratings in movie_ratings.items():
        score = sum(ratings[genre] for genre in preferences if genre in ratings)
        movie_scores[movie] = score
    
    sorted_movies = sorted(movie_scores.items(), key=lambda x: x[1], reverse=True)
    top_recommendations = [movie for movie, _ in sorted_movies[:5]]
    return top_recommendations
#end top 10

#image header 
header_image = customtkinter.CTkImage(light_image=Image.open('Posters.jpg'),size=(400,250))
image_placement = customtkinter.CTkLabel(root, text="", image=header_image)    
image_placement.pack()    
#end image header

# Main function to run the recommendation system
heading = customtkinter.CTkLabel(root, text="Please choose a user", font=("Arial Bold", 25))
#heading.place Any placement using x as width and y as height
heading.place(x=220, y=251)
#end heading.place


#option menu 
choice = customtkinter.CTkOptionMenu(root, values=["Alice","Bob", "Charlie", "David","James"])
choice.pack(pady=40)
#end option menu

def main():
    #user = input("Enter your name: ")
    user = choice.get()
    recommendations = recommend_movies(user)
    if recommendations:
        #print("Top movie recommendations for", user + ":")
        my_label = customtkinter.CTkLabel(root, text="Top 3 movie recommendation for: " +str(user), font=("Arial Bold", 20) )
        my_label.pack(pady=20)
    for i, movie in enumerate(recommendations, 1):        
        my_label2 = customtkinter.CTkLabel(root, text=(f"{i}. {movie}"), font=("Arial", 18))
        my_label2.pack(pady=1)        
            #print(f"{i}. {movie}")
    else:
        my_label3 = customtkinter.CTkLabel(root, text="")
        my_label3.pack(pady=1)
       #print("Sorry, no recommendations available.")

def top5():
    #user = input("Enter your name: ")    
    global my_label2
    user = choice.get()
    recommendations = recommend_movies_top5(user)
    
    if recommendations:
        #print("Top movie recommendations for", user + ":")
        my_label = customtkinter.CTkLabel(root, text="Top 5 movie recommendation for: " +str(user), font=("Arial Bold", 20) )
        my_label.pack(pady=20)
    for i, movie in enumerate(recommendations, 1):
        my_label2 = customtkinter.CTkLabel(root, text=(f"{i}. {movie}"), font=("Arial", 18))
        my_label2.pack(pady=1)        
        my_label2.configure(text="")    
            #print(f"{i}. {movie}")
            
    else:
        my_label3 = customtkinter.CTkLabel(root, text="")
        my_label3.pack(pady=1)

def clear_text():
    global my_label2
    my_label2.configure(text="")
# Run the recommendation system
#my_label = customtkinter.CTkLabel(root, text="")
#my_label.pack(pady=10)

#button top 3
pick_button = customtkinter.CTkButton(root, text="Top 3 Recommend me Movie", command=main )
pick_button.pack(pady=10)

#button top 5
pick_button2 = customtkinter.CTkButton(root, text="Top 5 recommend me a movie", command=top5 )
pick_button2.pack(pady=10)

#clear
clear_button2 = customtkinter.CTkButton(root, text="Clear", command=clear_text )
clear_button2.pack(pady=10)
root.mainloop()

If I click the button "Top 5 recommend me a movie" there should be the list of movies that I added then if I try to click the button "Top 3 recommend me a movie" it should be replace with top 3 list of movies.


Solution

  • You create new set of labels whenever a pick button is clicked, so the new set of labels may not be visible because they are pushed down out of the window bottom.

    You can create a frame for those labels and you need to destroy previously created labels before showing new ones

    ...
    def main():
        clear_text()  # remove previously created labels
    
        user = choice.get()
        recommendations = recommend_movies(user)
        if recommendations:
            my_label = customtkinter.CTkLabel(view, text="Top 3 movie recommendation for: " +str(user), font=("Arial Bold", 20) )
            my_label.pack(pady=20)
        for i, movie in enumerate(recommendations, 1):
            my_label2 = customtkinter.CTkLabel(view, text=(f"{i}. {movie}"), font=("Arial", 18))
            my_label2.pack(pady=1)
        else:
            my_label3 = customtkinter.CTkLabel(view, text="")
            my_label3.pack(pady=1)
    
    def top5():
        clear_text()  # remove previously created labels
    
        user = choice.get()
        recommendations = recommend_movies_top5(user)
    
        if recommendations:
            my_label = customtkinter.CTkLabel(view, text="Top 5 movie recommendation for: " +str(user), font=("Arial Bold", 20) )
            my_label.pack(pady=20)
        for i, movie in enumerate(recommendations, 1):
            my_label2 = customtkinter.CTkLabel(view, text=(f"{i}. {movie}"), font=("Arial", 18))
            my_label2.pack(pady=1)
            my_label2.configure(text="")
        else:
            my_label3 = customtkinter.CTkLabel(view, text="")
            my_label3.pack(pady=1)
    
    def clear_text():
        for w in view.winfo_children():
            w.destroy()
    
    ...
    
    # create a frame for the labels
    view = customtkinter.CTkFrame(root, fg_color="transparent", height=1)
    view.pack()
    
    root.mainloop()