Agis Soleas
Agis Soleas

Reputation: 343

QtGui.QMovie gif stops when function executes

I want to show a loading gif until a function is completed.

The code I have is

 self.LoadingGif = QtGui.QLabel(MainWindow)
 movie = QtGui.QMovie("hashUpdate.gif")
 self.LoadingGif.setMovie(movie)
 self.LoadingGif.setAlignment(QtCore.Qt.AlignCenter)
 self.gridLayout_2.addWidget(self.LoadingGif, 4, 1, 1, 1)
 movie.start()
 self.MYFUNCTION()

The problem is that the gif shows but it is not playing. It starts to play only when the function is completed.
How can I make the gif play while the function is executing ?

Upvotes: 0

Views: 1955

Answers (2)

three_pineapples
three_pineapples

Reputation: 11849

The GIF stops playing because your function self.MYFUNCTION is blocking the Qt Event loop. The Event loop is the part of Qt which (among other things) processes mouse/keyboard events, handles redrawing of widgets (like buttons when you hover over them or click on them) and updating the current frame displayed when playing an animation.

So the Qt event loop is responsible for executing your code in response to various things that happen in your program, but while it is executing your code, it can't do anything else.

So you need to change your code. There are several solutions to this:

  • Run MYFUNCTION in a secondary thread so it doesn't block the Qt event loop. However, this is not an option if your function interacts with the Qt GUI in any way. If you call any Qt GUI methods in MYFUNCTION (like updating a label, or whatever), this must never be done from a secondary thread (if you try, your program will randomly crash). It is recommended to use a QThread with Qt rather than a Python thread, but a Python thread will work fine if you don't ever need to communicate back to the main thread from your function.

  • If MYFUNCTION runs for a long time because you have a for/while loop, you could consider using a QTimer to periodically call the code in the loop. Control is returned to the Qt event loop after a QTimer executes so it can deal with other things (like updating your animation) between iterations of your loop.

  • Periodically call QApplication.instance().processEvents() during your function. This also returns control to the Qt event loop, but you may get unexpected behaviour if your function is also doing things with Qt.

Upvotes: 5

cdonts
cdonts

Reputation: 9599

You'll need to move self.your_function to another thread, letting Qt update the GUI and so your GIF!

Upvotes: 1

Related Questions