Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct
QMovie displays GIF with delay.
BigZet last edited by BigZet
I try to create Loader screen with GIF showing that data is processed.
I use PyQT5 and widgets.
I created QLabel and I set movie on it.
I works fine when I test it as standalone app.
But when I use it in my target app dialogs shows up, but animation is loaded after logic processing data is finished. Any other actions made on gui (showing progress bar etc) are not working as well.
I've read that it is caused by fact that GUI thread is to busy. Is there anything I can do about this?
Can I start this widget in separate thread?
I tried to call processEvents() before showing dialog but it does not help.
UPDATE: I put processEvents() in few more places during logic processing and it works fine, however I'm not sure if this is good practice to do so manually. Is there better solution?
Looks like your a blocking the event loop with your data processing.
Without seeing your code is hard to tell but needing to sprinkle calls to processEvent everywhere is sign of a big design issue.
Thank you for your response.
It's quite big application so I can't paste whole code, but I will try to give the essence of it:
if __name__ == "__main__": oldHook = sys.excepthook sys.excepthook = catchExceptions app = QApplication() engine = ToolEngine() #inherits from QObject (emits signals and performs main logic, but not as slots, functions are called from another functions created in MainWindow.py window = MainWindow(engine) window.show() # customizing exceptions hook due to fact that some exceptions were not shown in interactive console in PyCharm log.debug("App exec") retCode = app.exec_() sys.exit(retCode)
and file with MainWindow.py:
class MainWindow(QMainWindow): def __init__(self, engine, *args): #.... uic.loadUi(guiPath, self) # quite complex ui file with table, grids etc self.backend = engine # can this method of passing backend be a problem? #... self.buttonSave.clicked.connect(self.backend.saveChanges) #function not slot self.someButton.clicked.connect(self.someFunction1) #function not slot self.backend.saveStarted.connect(self.showLoadingScreen) #shows QWidget with Label containing QMovie def someFunction1(self): self.backend.doSomeCalculations()
Can you see anything wrong basing on those snippets or thats not clear/enough?
self.backend = engine # can this method of passing backend be a problem?
No, it's just an assignment.
self.backend.saveStarted.connect(self.showLoadingScreen) #shows QWidget with Label containing QMovie
What I suspect is that the method which emit saveStarted then does a lot of long stuff thus blocking the event loop hence the movie not playing as you'd expect.
So I should do this on separate thread to not block GUI thread?
Not knowing what you do in it I can't really comment on whether threading or reworking your code is the best solution.
Ok, I understand. Thank you for your help!
I had so many problems making Python work with widgets that I will probably rewrite it to QML.
That won't change anything if you are blocking the event loop be it with widgets or QtQuick, you'll have similar issue.
I highly recommend to fix the blocking parts so you can more freely change the GUI stack if you really want to.