QtGui.QMovie gif останавливается при выполнении функции

Я хочу показать загрузочный GIF, пока функция не будет завершена.

Код у меня есть

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

Проблема в том, что GIF показывает, но он не играет. Воспроизведение начинается только после завершения функции.
Как я могу заставить gif играть во время выполнения функции?

2 ответа

Решение

GIF перестает играть, потому что ваша функция self.MYFUNCTION блокирует цикл событий Qt. Цикл Event является частью Qt, которая (помимо прочего) обрабатывает события мыши / клавиатуры, обрабатывает перерисовку виджетов (например, кнопок, когда вы наводите на них курсор или нажимаете на них) и обновляет текущий кадр, отображаемый при воспроизведении анимации.

Таким образом, цикл событий Qt отвечает за выполнение вашего кода в ответ на различные вещи, происходящие в вашей программе, но пока он выполняет ваш код, он не может делать ничего другого.

Так что вам нужно изменить свой код. Есть несколько решений для этого:

  • Бежать MYFUNCTION во вторичном потоке, чтобы он не блокировал цикл событий Qt. Однако это не вариант, если ваша функция каким-либо образом взаимодействует с графическим интерфейсом Qt. Если вы вызываете любые методы Qt GUI в MYFUNCTION (например, обновление метки или что-то еще), это никогда не должно выполняться из вторичного потока (если вы попытаетесь, ваша программа будет случайно аварийно завершать работу). Рекомендуется использовать QThread с Qt, а не с потоком Python, но поток Python будет работать нормально, если вам никогда не нужно возвращаться к основному потоку из вашей функции.

  • Если MYFUNCTION работает долго, потому что у вас есть for/while цикл, вы могли бы рассмотреть возможность использования QTimer периодически вызывать код в цикле. Элемент управления возвращается в цикл событий Qt после QTimer выполняется так, что он может иметь дело с другими вещами (например, обновление анимации) между итерациями вашего цикла.

  • Периодически звоните QApplication.instance().processEvents() во время вашей функции. Это также возвращает управление в цикл событий Qt, но вы можете получить неожиданное поведение, если ваша функция также работает с Qt.

Вам нужно будет двигаться self.your_function в другой поток, позволяя Qt обновлять графический интерфейс и, следовательно, ваш GIF!

Другие вопросы по тегам