pythontkinterlagtkinter-scale

Tkinter scale gets stuck each time a function is called


I have a problem where the tkinter Scale widget seems to get stuck whenever I run a seemingly big function.

This is the code:

from tkinter import Tk, Button, Frame, Scale

root = Tk()

slider = Scale(root, orient='horizontal')
slider.pack()

frame = Frame(root)
frame.pack()

num = 0


def buttons():
    for widget in frame.winfo_children():
        widget.destroy()

    for i in range(50):
        Button(frame, text='Button' + str(i)).pack()


def basic():
    global num
    slider.set(num)
    num += 1
    print(num)
    if num <= 100:
        slider.after(100, basic)


if __name__ == '__main__':
    buttons()
    basic()

root.bind('<space>', lambda x: buttons())
root.mainloop()

What I want my program to do is update the slider normally even when I press 'Space' (meaning calling the buttons() function)
If you watch closely each time you press Space the slider will get stuck a little.
Since I'm using the slider for an Mp3 player in order to show time elapsed, this loss of time is extremely important for example for audio files of 10 or so seconds since the slider falls behind a lot making it seem as if it's working wrong \

I'd also like to point out that destroying the buttons and then repacking them is necessary for me.
I suspect that this happens because the program has to go over the buttons() function something that takes time since it's creating 50 buttons. Or am I mistaken?

Can I avoid that lag?

PS: As I mentioned in my comment:

I normally have a button that renames a (button) which is a song and in order for them to alphabetically ordered after renaming i need to recall the function that draws them. If I only configure tha name of the button (and not redraw them), it will stay in place and not move down or up depending on its name, while on the actual directory the order will change leading to inappropriate behavior such as playing the same song

Here are some images for better understanding: Before renamingAfter renaming

Thanks in advance!


Solution

  • Look at this code:

    import tkinter as tk
    
    def config_buttons():
        # Get the `text` of the first button
        starting_value = int(buttons[0].cget("text")) + 1
        # Iterate over all of the buttons
        for i, button in enumerate(buttons, start=starting_value):
            # Change the button's `text` and `command` atributes
            button.config(text=i, command=lambda i=i:print("Clicked %i"%i))
    
    root = tk.Tk()
    buttons = []
    
    add_button = tk.Button(root, text="+1 on all buttons", command=config_buttons)
    add_button.pack()
    
    for i in range(50):
        button = tk.Button(root, text=i, command=lambda i=i:print("Clicked %i"%i))
        button.pack()
        buttons.append(button)
    
    root.mainloop()
    

    When the add_button buttons is pressed, I iterate over all of the buttons and change their text and command attributes. As I am not creating new buttons, the function runs very fast.

    You can implement something similar in your code. Basically, avoid creating new buttons and just update the ones you already have on the screen.