GLHF GLHF - 6 months ago 55
Python Question

PyQt5 does not change gifs

I have an issue that I can't change gifs on

QMainWindow
. I'm reading a string from a json file, that json file is changing everytime. So for example, if the string from json file is
aaa
, I want to play
aaa.gif
on the
QMainWindow
, if the string is
bbb
I want to play
bbb.gif
. I already have 2 gifs, but the problem is, when the string in json file is changed, the gif are not. Codes are not long, just take a look;

from PyQt5.QtWidgets import (QMessageBox,QApplication, QWidget, QToolTip, QPushButton,
QDesktopWidget, QMainWindow, QAction, qApp, QToolBar, QVBoxLayout,
QComboBox,QLabel,QLineEdit,QGridLayout,QMenuBar,QMenu,QStatusBar,
QTextEdit,QDialog,QFrame,QProgressBar
)
from PyQt5 import QtCore, QtWidgets, QtGui
from PyQt5.QtGui import QIcon,QFont,QPixmap,QPalette
from PyQt5.QtCore import QCoreApplication, Qt,QBasicTimer, QTimer,QPoint
import PyQt5.QtWidgets,PyQt5.QtCore
import time,random,subprocess,sys,json

class cssden(QMainWindow):
def __init__(self):
super().__init__()


self.mwidget = QMainWindow(self)
self.setWindowFlags(QtCore.Qt.FramelessWindowHint)

self.setFixedSize(1400,923)
self.center

#timer
self.timer = QTimer(self)
self.timer.timeout.connect(self.timer_)
self.timer.start(0)

#gif
self.moviee = QLabel(self)
self.movie = QtGui.QMovie("aaa.gif")
self.moviee.setMovie(self.movie)
self.moviee.setGeometry(5,-80,380,250)
self.movie.start()

self.show()
def timer_(self):
with open ("mode.json") as tt:
self.mode = json.load(tt)
print (self.mode)
if self.mode == "bbb":
self.movie = QtGui.QMovie("bbb.gif")
#self.moviee.setGeometry(400,200,380,250) #
else: #----] I tried this but not working
self.movie = QtGui.QMovie("aaa.gif") #

#center of the screen
def center(self):
qr = self.frameGeometry()
cp = QDesktopWidget().availableGeometry().center()
qr.moveCenter(cp)
self.move(qr.topLeft())

app = QApplication(sys.argv)
app.setStyleSheet("QMainWindow{background-color: rgb(30,30,30);border: 1px solid black}")

ex = cssden()
sys.exit(app.exec_())


I also tried to re-define whole
QMovie
object aswell(from self.moviee to self.movie.start) but didn't work. The gif doesn't change nor play, also I set the coordinates after
if self.mode == "bbb"
to another place of the window to see maybe last gif is blocking the new gif, but no. It actually doesn't play the new gif. How can I solve this?

Answer

The main problem was the timer. Using timer.start(0) was skipping the update of the GUI between the calls to the timer, and so the gifs were changing, but not playing between the calls, because there was to no time. Setting the timeout at a value like 500 (=0.5s) will solve the problem while still being quick enough for the work to do (also, see comment below) :

timer.start(10)

The following code works for me. I added another timer to change the json file for the test but your don't need it since you must change it somewhere else.

   from PyQt5.QtWidgets import (QMessageBox,QApplication, QWidget, QToolTip, QPushButton,
                                 QDesktopWidget, QMainWindow, QAction, qApp, QToolBar, QVBoxLayout,
                                 QComboBox,QLabel,QLineEdit,QGridLayout,QMenuBar,QMenu,QStatusBar,
                                 QTextEdit,QDialog,QFrame,QProgressBar
                                 )
    from PyQt5 import QtCore, QtWidgets, QtGui
    from PyQt5.QtGui import QIcon,QFont,QPixmap,QPalette
    from PyQt5.QtCore import QCoreApplication, Qt,QBasicTimer, QTimer,QPoint
    import PyQt5.QtWidgets,PyQt5.QtCore

    import time,random,subprocess,sys,json

    class cssden(QMainWindow):
        def __init__(self):
            super(cssden, self).__init__()


            self.mwidget = QMainWindow(self)
            self.setWindowFlags(QtCore.Qt.FramelessWindowHint)

            self.setFixedSize(1400,923)

            self.center()

            #timer
            self.timer = QTimer(self)
            self.timer.timeout.connect(self.timer_)
            self.timer.start(1000)                       # changed timer timeout to 1s

            self.timer2 = QTimer(self)                 # I added
            self.timer2.timeout.connect(self.timer2_)  # this, but
            self.timer2.start(500)                     # you can remove it

            #gif
            self.moviee = QLabel(self)
            self.movie = QtGui.QMovie("aaa.gif")
            self.moviee.setMovie(self.movie)
            self.moviee.setGeometry(5,-80,380,250)
            self.movie.start()
            self.show()

        def timer2_(self):                # You can
            tt = open("mode.json", 'w')   # remove
            i = random.randint(0,1)       # that too
            if i == 1:                    #
                json.dump('aaa', tt)      #
            elif i == 0:                  #
                json.dump('bbb', tt)      #
            tt.close()                    #


        def timer_(self):
            tt = open("mode.json", 'r')
            self.mode = json.load(tt)
            tt.close()
            print (self.mode)
            if self.mode == "bbb":
                self.movie = QtGui.QMovie("bbb.gif")
                self.moviee.setMovie(self.movie)     # I added
                self.movie.start()                   # those lines
            else:                                          
                self.movie = QtGui.QMovie("aaa.gif")
                self.moviee.setMovie(self.movie)     # and here
                self.movie.start()                   # too

        #center of the screen
        def center(self):
            qr = self.frameGeometry()
            cp = QDesktopWidget().availableGeometry().center()
            qr.moveCenter(cp)
            self.move(qr.topLeft())

    app = QApplication(sys.argv)
    app.setStyleSheet("QMainWindow{background-color: rgb(30,30,30);border: 1px solid black}")

    ex = cssden()
    sys.exit(app.exec_())