Python – PyQt QFileDialog exec_ is slow

PyQt QFileDialog exec_ is slow… here is a solution to the problem.

PyQt QFileDialog exec_ is slow

I’m using a custom QFileDialog because I want to select multiple directories.
But the exec_ function is slow and I don’t understand why. I’m using the latest version of PyQt.

Code snippet:

from PyQt4 import QtGui, QtCore, QtNetwork, uic

class MainWindow(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        uic.loadUi('gui.ui', self)            
        self.connect(self.multiPackerAddDirsBtn,
                     QtCore.SIGNAL('clicked()'), self.multiPackerAddDirs)

def multiPackerAddDirs(self):
        dialog = QtGui.QFileDialog(self)
        dialog.setFileMode(QtGui.QFileDialog.Directory)
        dialog.setOption(QtGui.QFileDialog.ShowDirsOnly, True)
        dialogTreeView = dialog.findChild(QtGui.QTreeView)
        dialogTreeView.setSelectionMode(
            QtGui.QAbstractItemView.ExtendedSelection)
        if dialog.exec_():
            for dirname in dialog.selectedFiles():
                self.multiPackerDirList.addItem(str(dirname))
                print(str(dirname))

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    window = MainWindow()
    window.show()
    app.exec_()

Solution

The QFileDialog constructor creates a Qt dialog box, while a static function such as getSaveFileName creates a local dialog box unless DontUseNativeDialog option set to correct).

Local dialogs may be faster or slower than Qt’s, depending on the platform being used.

For some platforms, though, the problem seems to be more serious. See this longstanding bug, which affects Windows XP and Windows 7 (among others) with Qt 4.7/4.8.

Update

To be clear:

On Windows, the static function QFileDialog.getExistingDirectory Opens the native Browse for Folder dialog box, which allows you to select only one directory. So Qt can’t provide a native dialog for selecting multiple directories because Windows doesn’t.

Another major alternative is to use Qt’s own non-local file dialog and follow this faq is recommended in to monkey patch it. But, as you’ve already discovered, this currently has a nasty slowness drawback due to bugs in the underlying implementation.

The only options left are to either write your own directory listing dialog or try to come up with another way to solve the problem at hand (i.e. not using a file dialog).

Related Problems and Solutions