Search code examples
python-3.xtkintergifvlc

Gif animation with tkinter and classes in Python 3


I'm having some problems making my gif work in this code. its a kind of media player with a graphic equalizer :) I'm trying to make gif play inside the "pantalla" label. I'm having an attribute error with the frame variable. I've been looking around but cannot solve the problem. sorry for my mistakes I'm a newbie. any help will be appreciated.

here the code:


import os
from tkinter import *
from vlc import Instance
import time


app = Tk()
app.title("JlMultimedia")
app.iconbitmap("C:/Users/Thunder/Documents/Projects/Python/auricular.ico")
app.geometry("340x250")
app.config(bg="blue")

frames = [PhotoImage(file='C:/Users/Thunder/Documents/Projects/Python/imagenes/equalizer1.gif', format = 'gif -index %i' %(i)) for i in range(5)]

def update(self, ind):
    self.frame = frames[ind]
    ind += 1
    print(ind)
    if ind>4: #With this condition it will play gif infinitely
        ind = 0
    app.after(100, update, ind)

class Jlmultimedia:

    def __init__(self):
        self.Player = Instance('--loop')
        

        capa = Frame(app)
        capa.config(bg="#ffffff")
        capa.pack(expand="1")


        capa1 = Frame(capa, bg="#0000ff")
        capa1.config()
        capa1.pack(expand="1")

       
        pantalla = Label(capa1, image=self.frame)
        pantalla.grid(row="0", columnspan="3")
        

        self.playimage = PhotoImage(file="C:/Users/Thunder/Documents/Projects/Python/imagenes/play4.png")
        self.stopimage = PhotoImage(file="C:/Users/Thunder/Documents/Projects/Python/imagenes/stop4.png")
        self.pauseimage = PhotoImage(file="C:/Users/Thunder/Documents/Projects/Python/imagenes/pause4.png")
        self.nextimage = PhotoImage(file="C:/Users/Thunder/Documents/Projects/Python/imagenes/forw4.png")
        self.backimage = PhotoImage(file="C:/Users/Thunder/Documents/Projects/Python/imagenes/rew4.png")

        capa2 = LabelFrame(capa)
        capa2.config(bg="#ffffff")
        capa2.pack(expand="1")

        playboton = Button(capa2, image=self.playimage, bd="0", command=self.play)
        playboton.grid(row="1", column="1")

        self.volVar = IntVar()
        volboton = Scale(capa2, from_=100, to=0, resolution=1, length=90, 
        label="Vol", variable=self.volVar, command=self.set_volume)
        volboton.grid(row="1", column="6")
                     
        stopboton = Button(capa2, image=self.stopimage, bd="0", command=self.stop)
        stopboton.grid(row="1", column="2")

        pauseboton = Button(capa2, image=self.pauseimage, bd="0", command=self.pause)
        pauseboton.grid(row="1", column="4")

        nextboton = Button(capa2, image=self.nextimage, bd="0", command=self.next)
        nextboton.grid(row="1", column="3")

        preboton = Button(capa2, image=self.backimage, bd="0", command=self.previous)
        preboton.grid(row="1", column="5")

        # panel to hold player time slider
        self.timeVar = DoubleVar()
        self.timeSliderLast = 0
        self.timeSlider = Scale(capa1, variable=self.timeVar, command=self.OnTime, 
                                       from_=0, to=1000, orient=HORIZONTAL, length=328, showvalue=0)  # label='Time',
        #self.timeSlider.pack(side=BOTTOM, fill=X, expand=1)
        self.timeSliderUpdate = time.time()
        self.timeSlider.grid(row="1", columnspan="5")

    def addPlaylist(self):
        self.mediaList = self.Player.media_list_new()
        path = r"C:/Users/Thunder/Documents/Projects/Python/musica"
        songs = os.listdir(path)
        for s in songs:
            self.mediaList.add_media(self.Player.media_new(os.path.join(path,s)))
        self.listPlayer = self.Player.media_list_player_new()
        self.listPlayer.set_media_list(self.mediaList)

    def set_volume(self, *unuse):
        vol = min(self.volVar.get(), 100)
        self.listPlayer.get_media_player().audio_set_volume(vol)

    def play(self):
        self.listPlayer.play()
    def next(self):
        self.listPlayer.next()
    def pause(self):
        self.listPlayer.pause()
    def previous(self):
        self.listPlayer.previous()
    def stop(self):
        self.listPlayer.stop()

    def OnTime(self, *unused):
        if self.listPlayer:
            t = self.timeVar.get()
            if self.timeSliderLast != int(t):
                self.listPlayer.get_media_player().set_time(int(t * 1e3))  # milliseconds
                self.timeSliderUpdate = time.time()

myPlayer = Jlmultimedia()
myPlayer.addPlaylist()


app = mainloop()


Solution

  • There are several issues:

    • update() has never been executed
    • image option of label pantalla should be update as well inside update()
    • pantalla is a local variable inside Jlmultimedia.__init__(), you should make it instance variable self.pantalla
    • self.frame is undefined
    • app = mainloop() should be app.mainloop()

    Below is a modified update():

    def update(ind=0):
        myPlayer.pantalla.config(image=frames[ind%len(frames)])
        app.after(100, update, ind+1)
    

    And changing pantalla to instance variable inside __init__():

    class Jlmultimedia:
        def __init__(self):
            ...
            self.pantalla = Label(capa1)
            self.pantalla(row=0, columnspan=3)
            ...
    

    Then call update() before app.mainloop():

    ...
    update()
    app.mainloop()