[Python] Tkinter widget not being tracked properly

Discussão em 'Python' iniciado por Stack, Fevereiro 18, 2025.

  1. Stack

    Stack Membro Participativo

    In this code, hitting the weightpos/weightneg buttons should change the value by 5. When using the original buttons that arent created from the addrow() function, it works fine, but using the created buttons it only increments by 1.

    Code:

    import tkinter as tk
    from tkinter import ttk
    from tkinter import *
    from PIL import ImageTk, Image
    import os
    weight_entry='0'
    root=tk.Tk()

    movement_chest = ["Flat Bench", 'Incline Bench', 'Decline Bench', 'Flat DB Press', "Incline DB Press", 'High-Low Cable Raise', "Low-High Cable Raise",]
    files_movement_chest = ["flat_bench.gif", 'incline_bench.gif', 'decline_bench.gif', 'db_flat.gif', "db_incline.gif", 'high_low_cable.gif', "low_high_cable.gif",]
    row_counter=1

    class Toolbar(Frame):
    def __init__(self):
    super().__init__()
    self.initUI()

    def initUI(self):
    self.master.title("Workout Tracker")
    menubar = Menu(self.master)
    self.master.config(menu=menubar)

    fileMenu = Menu(menubar)
    fileMenu.add_command(label="Exit", command=self.onExit)
    menubar.add_cascade(label="File", menu=fileMenu)

    def onExit(self):
    self.quit()

    # Create a variable to hold the image reference
    image_label = None
    img = None

    # Set button function
    def plusminus(increment, entry, row_counter):
    if entry.get() == '':
    new_value = 0
    else:
    current_value = int(entry.get()) # Get the current value from the entry widget
    if entry == weight_entry:
    # If the entry widget is the weight field, change the value by 5
    if increment:
    new_value = current_value + 5
    else:
    new_value = current_value - 5
    else:
    # For other fields like sets, change by 1
    if increment:
    new_value = current_value + 1
    print(entry)
    else:
    new_value = current_value - 1

    if new_value < 0:
    new_value = 0

    entry.delete(0, tk.END) # Clear the entry
    entry.insert(0, str(new_value)) # Insert the new value


    def on_combobox_select(event=None, row_counter=0): # Allow for manual function call (no event)
    global image_label, img # Use global variables
    motion = Dropdown.get()

    # Remove the old image if it exists
    if image_label:
    image_label.destroy()

    # Find the index of the selected motion in movement_chest
    if motion in movement_chest:
    index = movement_chest.index(motion) # Get the index of the selected motion

    # Get the corresponding filename for the selected motion
    img_path = files_movement_chest[index]

    # Check if the image file exists and load it
    if os.path.exists(img_path):
    img = ImageTk.PhotoImage(Image.open(img_path))
    else:
    print(f"Image file '{img_path}' not found.")
    img = None

    # Only add the label if the image is loaded correctly
    if img:
    image_label = Label(root, image=img)
    image_label.grid(row=row_counter, column=0, columnspan=3, sticky="nsew") # Use grid here with spanning
    else:
    img_path = "workout.gif"
    if os.path.exists(img_path):
    img = ImageTk.PhotoImage(Image.open(img_path))
    else:
    print("Image file 'workout.gif' not found.")
    img = None
    if img: # Only add the label if the image is loaded correctly
    panel = Label(root, image=img)
    panel.grid(row=row_counter, column=0, columnspan=3, sticky="nsew") # Use grid here with spanning

    # Create a function that adds a new row of widgets
    def add_row():
    global row_counter

    # Add row-specific widgets like motion dropdown, weight entry, set entry, etc.
    label_dropdown = tk.Label(root, text='Motion')
    label_dropdown.grid(row=row_counter, column=4, pady=(15, 0), sticky='n')

    # Create a new row of widgets for motion
    motion_dropdown = ttk.Combobox(
    root,
    values=movement_chest,
    state="readonly",
    )
    motion_dropdown.grid(row=row_counter, column=4, padx=5, pady=5)
    motion_dropdown.bind("<<ComboboxSelected>>", lambda event: on_combobox_select(event, row_counter))

    # Create weight entry for this row
    label_weight = tk.Label(root, text='Weight')
    label_weight.grid(row=row_counter, column=5, pady=(15, 0), sticky='n')

    weight_entry = ttk.Entry(root)
    weight_entry.grid(row=row_counter, column=5, padx=5, pady=5)

    # Buttons for incrementing/decrementing weight
    btn_weightpos = tk.Button(root, text='+', command=lambda: plusminus(True, weight_entry, row_counter))
    btn_weightpos.grid(row=row_counter, column=5, padx=(0, 19), pady=(0, 8), sticky='s')

    btn_weightneg = tk.Button(root, text='-', command=lambda: plusminus(False, weight_entry, row_counter))
    btn_weightneg.grid(row=row_counter, column=5, padx=(19, 0), pady=(0, 8), sticky='s')

    # Create set entry for this row
    label_set = tk.Label(root, text='Sets')
    label_set.grid(row=row_counter, column=6, pady=(15, 58), sticky='n')

    set_entry = ttk.Entry(root)
    set_entry.grid(row=row_counter, column=6, padx=5, pady=5)

    # Buttons for incrementing/decrementing sets
    btn_setpos = tk.Button(root, text='+', command=lambda: plusminus(True, set_entry, row_counter))
    btn_setpos.grid(row=row_counter, column=6, padx=(0, 19), pady=(0, 8), sticky='s')

    btn_setneg = tk.Button(root, text='-', command=lambda: plusminus(False, set_entry, row_counter))
    btn_setneg.grid(row=row_counter, column=6, padx=(19, 0), pady=(0, 8), sticky='s')

    # Create an image label placeholder for each row (so that we can update it later)
    image_label = None
    img = None

    # Increment row_counter for the next row
    row_counter += 1

    # Dropdown (Combobox)
    Dropdown = ttk.Combobox(
    root,
    values=movement_chest,
    state="readonly",
    )
    label_dropdown = tk.Label(root, text='Motion')
    label_dropdown.grid(row=0, column=4, pady=(70, 0), sticky='n')
    Dropdown.grid(row=0, column=4, padx=5, pady=5)
    Dropdown.bind("<<ComboboxSelected>>", on_combobox_select)

    # Weight field
    label_weight = tk.Label(root, text='Weight')
    weight_entry = ttk.Entry(root, text='Weight')
    label_weight.grid(row=0, column=5, pady=(70, 0), sticky='n')
    weight_entry.grid(row=0, column=5, padx=5, pady=5)
    # button to increment the weight value
    btn_weightpos = tk.Button(root, text='+', command=lambda: plusminus(True, weight_entry, 0)) # Using lambda to pass argument
    btn_weightpos.grid(row=0, column=5, padx=(0, 19), pady=(0, 65), sticky='s')
    # button to decrement the weight value
    btn_weightneg = tk.Button(root, text='-', command=lambda: plusminus(False, weight_entry, 0))
    btn_weightneg.grid(row=0, column=5, padx=(19, 0), pady=(0, 65), sticky='s')

    # Set field
    label_set = tk.Label(root, text='Sets')
    set_entry = ttk.Entry(root, text='Sets')
    label_set.grid(row=0, column=6, pady=(70, 0), sticky='n')
    set_entry.grid(row=0, column=6, padx=5, pady=5)
    # button to increment the set value
    btn_setpos = tk.Button(root, text='+', command=lambda: plusminus(True, set_entry, 0)) # Using lambda to pass argument
    btn_setpos.grid(row=0, column=6, padx=(0, 19), pady=(0, 65), sticky='s')
    # button to decrement the set value
    btn_setneg = tk.Button(root, text='-', command=lambda: plusminus(False, set_entry, 0))
    btn_setneg.grid(row=0, column=6, padx=(19, 0), pady=(0, 65), sticky='s')

    # Manually trigger the combobox selection to load the default image (workout.gif)
    on_combobox_select()
    # Add "Add Row" button
    add_row_button = tk.Button(root, text="Add Row", command=add_row)
    add_row_button.grid(row=0, column=7, padx=5, pady=5)

    # Initial row setup (first row)

    root.mainloop()


    I tried using variables instead of weight_entry when calling the function and it did not work

    Continue reading...

Compartilhe esta Página