在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函数完成之前保持无响应。
我该怎么避免呢?

最佳答案

经验教训:如果有一些长时间运行的操作要做——例如,读或写一个大文件,请将它们移到另一个线程,否则它们将冻结用户界面。
因此,我创建了一个子类QThreadMovieMaker,其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用于向用户显示电影编码的工作进度。

10-08 00:30