3

私の 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関数が完了するまでアプリケーション全体が応答しません。

これを避けるにはどうすればよいですか?

4

1 に答える 1

2

教訓:大きなファイルの読み取りや書き込みなど、長時間実行する操作がある場合は、それらを別のスレッドに移動しないと、UI がフリーズします。

したがって、 のサブクラスを作成しました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)
このようなシグナルはスレッドによって発行され、映画のエンコーディング作業の進行状況をユーザーに示すために使用されるQProgressDialogMovieMakerを更新します。

于 2013-03-01T20:33:53.803 に答える