PyQt5不会改变gif

PyQt5 does not change gifs

我有一个问题,我无法在 QMainWindow 上更改 gif。我正在从 json 文件中读取一个字符串,那个 json 文件每次都在变化。例如,如果来自 json 文件的字符串是 aaa,我想在 QMainWindow 上播放 aaa.gif,如果字符串是 bbb 我想播放 bbb.gif。我已经有 2 个 gif,但问题是,当 json 文件中的字符串更改时,gif 却没有。代码不长,随便看看;

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_())

我也尝试重新定义整个 QMovie 对象(从 self.moviee 到 self.movie.start)但没有成功。 gif 既没有改变也没有播放,我也将 if self.mode == "bbb" 之后的坐标设置到 window 的另一个位置,看看最后一个 gif 是否阻止了新的 gif,但是没有。它实际上不播放新的 gif。我该如何解决这个问题?

主要问题是计时器。使用 timer.start(0) 会在调用计时器之间跳过 GUI 的更新,因此 gif 会发生变化,但不会在调用之间播放,因为没有时间。将超时设置为 500(=0.5s)这样的值将解决问题,同时仍然足够快地完成工作(另请参见下面的评论):

timer.start(10)

以下代码适用于我。我添加了另一个计时器来更改 json 文件以进行测试,但您不需要它,因为您必须在其他地方更改它。

   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_())