我希望在函数完成之前显示一个加载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播放?
答案 0 :(得分:5)
GIF停止播放,因为您的函数self.MYFUNCTION
阻止了Qt事件循环。事件循环是Qt的一部分,其中(除其他外)处理鼠标/键盘事件,处理小部件的重绘(当您将鼠标悬停在按钮上或点击它们时按钮)以及更新播放动画时显示的当前帧。 p>
因此,Qt事件循环负责执行代码以响应程序中发生的各种事情,但在执行代码时,它无法执行任何其他操作。
因此您需要更改代码。有几种解决方案:
在辅助线程中运行MYFUNCTION
,因此它不会阻止Qt事件循环。但是,如果您的函数以任何方式与Qt GUI交互,那么不是一个选项。如果你在MYFUNCTION
中调用任何Qt GUI方法(比如更新标签,或者其他),这绝不能从辅助线程完成(如果你尝试,你的程序将随机崩溃)。建议在Qt而不是Python线程中使用QThread
,但如果您不需要从函数中回传到主线程,则Python线程可以正常工作。
如果MYFUNCTION
因为您有for
/ while
循环而长时间运行,您可以考虑使用QTimer
定期调用代码循环。在执行QTimer
之后,控制权返回到Qt事件循环,因此它可以在循环的迭代之间处理其他事情(例如更新动画)。
在您的功能期间定期致电QApplication.instance().processEvents()
。这也会将控制权返回给Qt事件循环,但如果您的函数也使用Qt执行操作,则可能会出现意外行为。
答案 1 :(得分:1)
您需要将self.your_function
移至另一个thread,让Qt更新GUI以及您的GIF!