-2

How would you code a button, which changes its Image after you press it, but after 3 Seconds it changes Back to its normal state ?

I managed to change the Button Image with a Click, but the function sleep() stops the whole Tkinter Mainloop, which leads to the Button not doing anything.

Delrius Euphoria
  • 14,910
  • 3
  • 15
  • 46
  • 1
    Check out the `root.after(*ms*,*func*)` https://stackoverflow.com/questions/63118430/create-a-main-loop-with-tkinter/63118515#63118515 – Thingamabobs Oct 09 '20 at 17:36
  • 1
    Use the universal widget [after()](https://web.archive.org/web/20190222214221id_/http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/universal.html) method to schedule a call to a function that re-configures the `Button`'s `image` option as desired. Generally you'll always want to avoid using `time.sleep()` in tkinter apps because doing so interferes with its `mainloop()` and cause it to "hang". – martineau Oct 09 '20 at 17:56
  • There are many, many questions similar to this question on this site. – Bryan Oakley Oct 09 '20 at 18:44

1 Answers1

1

As mentioned above, you need to make another function which changes the image back. You would then schedule that function to run later using the after method. This would be an ideal place to use a Button subclass to make a custom type of Button that incorporates those functions and the image data. Like this:

import tkinter as tk

class EleckTroniiKz(tk.Button):
    """A new type of Button that shows one image, changes to another image
    when clicked, and changes back to the original image after 3 seconds"""
    def __init__(self, master=None, image1=None, image2=None, **kwargs):
        self.command = kwargs.pop('command', None)
        super().__init__(master, **kwargs)
        self.image1 = tk.PhotoImage(file=image1)
        self.image2 = tk.PhotoImage(file=image2)
        self.config(image=self.image1, command=self.on_click)

    def on_click(self):
        self.config(image=self.image2)
        if self.command: self.command()
        # schedule the after_click function to run 3 seconds from now
        self.after(3000, self.after_click)

    def after_click(self):
        self.config(image=self.image1)

### test / demo
def main():
    root = tk.Tk()
    btn = EleckTroniiKz(root, 'OFF.gif', 'ON.gif')
    btn.pack()
    root.mainloop()

if __name__ == '__main__':
    main()
Novel
  • 13,406
  • 2
  • 25
  • 41
  • 1
    I think this would be the best way, but I'm not sure if the OP knows how to use classes. – Thingamabobs Oct 09 '20 at 18:18
  • 2
    They may not know how to create classes, but they certainly can use them. And probably learn a little about creating them in the process. – Novel Oct 09 '20 at 18:25
  • I actually agree with @Atlas435 here, it would be more easier if the example given would more simple and direct right? This might as well just confuse an entire beginner. Just an opinion – Delrius Euphoria Oct 09 '20 at 21:44