在PyQt4应用程序中,有一个功能允许用户保存avi文件。
为此,在主窗口中实现了saveMovie方法:
def saveMovie(self):
""" Let the user make a movie out of the current experiment. """
filename = QtGui.QFileDialog.getSaveFileName(self, "Export Movie", "",
'AVI Movie File (*.avi)')
if filename != "":
dialog = QtGui.QProgressDialog('',
QtCore.QString(),
0, 100,
self,
QtCore.Qt.Dialog |
QtCore.Qt.WindowTitleHint)
dialog.setWindowModality(QtCore.Qt.WindowModal)
dialog.setWindowTitle('Exporting Movie')
dialog.setLabelText('Resampling...')
dialog.show()
make_movie(self.appStatus, filename, dialog)
dialog.close()
我的想法是使用一个QProgressDialog来显示视频编码工作是如何进行的。
尽管如此,在选择文件名之后,QFileDialog不会消失,整个应用程序在make_movie函数完成之前保持无响应。
我该怎么避免呢?
最佳答案
经验教训:如果有一些长时间运行的操作要做——例如,读或写一个大文件,请将它们移到另一个线程,否则它们将冻结用户界面。
因此,我创建了一个子类QThread
,MovieMaker
,其run
方法封装了先前由make_movie
实现的功能:
class MovieMaker(QThread):
def __init__(self, uAppStatus, uFilename):
QtCore.QThread.__init__(self, parent=None)
self.appStatus = uAppStatus
self.filename = uFilename
def run(self):
## make the movie and save it on file
让我们回到
saveMovie
方法。在这里,我用以下代码替换了对make_movie
的原始调用:self.mm = MovieMaker(self.appStatus,
filename)
self.connect(self.mm, QtCore.SIGNAL("Progress(int)"),
self.updateProgressDialog)
self.mm.start()
注意我如何定义一个新的信号,
Progress(int)
。这样的信号由
MovieMaker
线程发出,用于更新QProgressDialog,该QProgressDialog用于向用户显示电影编码的工作进度。