Search code examples
pythontkinter

How to display GIF or MP4


I know how to display video in Tkinter, but i don't found videos about a displaying GIF in custom Tkinter. Please Help.

        from PIL import Image
        self.logo = customtkinter.CTkImage(dark_image=Image.open('resources/images/background.gif'),
                                           size=(1282, 720))
        self.logo_label = customtkinter.CTkLabel(master=self, text='', image=self.logo)

Solution

  • To show an animated GIF, you need to load all the frames from the GIF image and store them as instances of customtkinter.CTkImage if you want to use a customtkinter.CTkLabel to display the frames. Then you can use .after() loop to show the frames one by one.

    Below is an example using a custom CTkLabel:

    import customtkinter as ctk
    from PIL import Image
    
    class GIFLabel(ctk.CTkLabel):
        def __init__(self, master, image_path, **kwargs):
            self._gif_image = Image.open(image_path)
            # set the size of the label to the same as the GIF image
            kwargs.setdefault("width", self._gif_image.width)
            kwargs.setdefault("height", self._gif_image.height)
            # don't show the text initially
            kwargs.setdefault("text", "")
            # delay for the after loop
            self._duration = kwargs.pop("duration", None) or self._gif_image.info["duration"]
            super().__init__(master, **kwargs)
            # load all the frames
            self._frames = []
            for i in range(self._gif_image.n_frames):
                self._gif_image.seek(i)
                self._frames.append(ctk.CTkImage(self._gif_image.copy(), size=(self["width"], self["height"])))
            # start animation
            self._animate()
    
        def _animate(self, idx=0):
            self.configure(image=self._frames[idx])
            self.after(self._duration, self._animate, (idx+1)%len(self._frames))
    
    app = ctk.CTk()
    
    label = GIFLabel(app, "any.gif")
    label.pack()
    
    app.mainloop()