3

I'm using a custom QFileDialog because I want to select multiple directories. But the exec_ function is very slow, and I can't figure out why. I'm using the newest 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_()
ekhumoro
  • 115,249
  • 20
  • 229
  • 336
Ahsous
  • 125
  • 2
  • 9
  • What platform are you on? Is the file-dialog *always* slow, or only when you use the code you've posted? – ekhumoro Nov 19 '12 at 19:22
  • I'm on Windows 7. If I use a predefined method like getSaveFileName its fast but if I create a custom dialog with dialog = QtGui.QFileDialog(self) and use dialog.exec_() it's slow as hell. – Ahsous Nov 19 '12 at 19:28

2 Answers2

4

The QFileDialog constructor creates a Qt dialog, whereas the static functions (like getSaveFileName) will create a native one (unless the DontUseNativeDialog option is set to True).

The native dialogs may be faster or slower than Qt's, depending on the platform in use.

For some plaforms, though, it appears the problem may be more acute. See this longstanding bug, which affects Windows XP and Windows 7 (amongst others) with Qt 4.7 / 4.8.

UPDATE

Just to be clear:

On Windows, the static function QFileDialog.getExistingDirectory opens the native "Browse For Folder" dialog, which only allows selecting a single directory. So Qt cannot provide a native dialog for selecting multiple directories, because Windows doesn't provide one.

The other main alternative is to use Qt's own, non-native file-dialog and monkey-patch it as suggested in this faq. However, as you've already discovered, this currently has the significant downside of being annoyingly slow due to bugs in the underlying implementation.

The only remaining alternatives are to either write your own directory-lister dialog, or try to think of another way of solving your immediate problem (i.e. without using a file-dialog).

ekhumoro
  • 115,249
  • 20
  • 229
  • 336
  • I tried to make DontUseNativeDialog False but it didn't had an effect. Is there another way to create a file dialog where I can select multiple directories? – Ahsous Nov 20 '12 at 20:38
  • @Ahsous. There's not much more to be said on this, but I've updated my answer as best I can. – ekhumoro Nov 20 '12 at 23:36
1

I had very very slow performance from the default Qt file browser dialog. Listing a directory took ~5s and selecting a file took ~3s. Adding the "DontUseNativeDialog" option fixed my problem completely.

file_path = QtGui.QFileDialog.getSaveFileName( self, 'Title', path, "", "", QtGui.QFileDialog.DontUseNativeDialog )
print file_path