Loris Fichera
Loris Fichera

Reputation: 98

PyQt: QtGui.QFileDialog.getSaveFileName won't close after selection

In my PyQt4 application, there is a functionality that allows users to save a avi file. To this aim, a saveMovie method has been implemented in the main window:

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

My idea is to use a QProgressDialog to show how the video encoding work is proceeding.
Nevertheless, after the selection of the filename, the QFileDialog won't disappear and the entire application stays unresponsive until the make_movie function has completed.

What should I do to avoid this?

Upvotes: 3

Views: 3799

Answers (1)

Loris Fichera
Loris Fichera

Reputation: 98

Lesson learned: if you have some long-running operations to do -- for example, reading or writing a big file, move them to another thread or they will freeze the UI.

Therefore, I created a subclass of QThread, MovieMaker, whose run method encapsulates the functionality previosly implemented by 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

Let's move back to the saveMovie method. Here, I replaced the original call to make_movie with the following code:

self.mm = MovieMaker(self.appStatus,
                     filename)

self.connect(self.mm, QtCore.SIGNAL("Progress(int)"),
             self.updateProgressDialog)

self.mm.start()

Note how I defined a new signal, Progress(int).
Such a signal is emitted by the MovieMaker thread to update the QProgressDialog used to show the user how the movie encoding work is progressing.

Upvotes: 2

Related Questions