1

This question already exists here, but the answer appears outdated or no longer works as of Python 2.7.

When I use this code to subclass my QFileDialog, the FileDialog class init is called, but the openClicked method is never called.

class FileDialog(QtGui.QFileDialog):
    def __init__(self, *args):
        QtGui.QFileDialog.__init__(self, *args)
        self.setOption(self.DontUseNativeDialog, True)
        self.setFileMode(self.ExistingFiles)
        btns = self.findChildren(QtGui.QPushButton)
        self.openBtn = [x for x in btns if 'open' in str(x.text()).lower()][0]
        self.openBtn.clicked.disconnect()
        self.openBtn.clicked.connect(self.openClicked)
        self.tree = self.findChild(QtGui.QTreeView)

    def openClicked(self):
        inds = self.tree.selectionModel().selectedIndexes()
        files = []
        for i in inds:
            if i.column() == 0:
                files.append(os.path.join(str(self.directory().absolutePath()),str(i.data().toString())))
        self.selectedFiles = files
        self.hide()

    def filesSelected(self):
        return self.selectedFiles

Is this the correct call for FileDialog?

mydialog = FileDialog()
filelist = mydialog.getExistingDirectory(self, "Select Stuff", "", QtGui.QFileDialog.DontConfirmOverwrite) 
ekhumoro
  • 115,249
  • 20
  • 229
  • 336
panofish
  • 7,578
  • 13
  • 55
  • 96

1 Answers1

3

The solution from the other question is unnecessarily complicated. All you need to do is override QFileDialog.accept(), and then you are free to implement whatever behaviour you like.

The example below is very minimal. It doesn't do any checking of the selected files (like seeing whether they still exist), but that could easily be added if necessary.

from PyQt4 import QtCore, QtGui

class FileDialog(QtGui.QFileDialog):
    def __init__(self, *args, **kwargs):
        super(FileDialog, self).__init__(*args, **kwargs)
        self.setOption(QtGui.QFileDialog.DontUseNativeDialog, True)
        self.setFileMode(QtGui.QFileDialog.ExistingFiles)

    def accept(self):
        super(FileDialog, self).accept()

class Window(QtGui.QWidget):
    def __init__(self):
        super(Window, self).__init__()
        self.button = QtGui.QPushButton('Test', self)
        self.button.clicked.connect(self.handleButton)
        layout = QtGui.QVBoxLayout(self)
        layout.addWidget(self.button)

    def handleButton(self):
        dialog = FileDialog()
        if dialog.exec_() == QtGui.QDialog.Accepted:
            print(dialog.selectedFiles())

if __name__ == '__main__':

    import sys
    app = QtGui.QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())
ekhumoro
  • 115,249
  • 20
  • 229
  • 336
  • Genius. Thanks, we are all at different levels of our understanding of this wonderful programming language.. some more or less than others. :) – panofish Nov 19 '14 at 02:35
  • I am getting : RuntimeError: super-class __init__() of type Window was never called – Rajiv Sharma Oct 10 '16 at 09:38
  • @cyclops. Thanks - should be fixed now. – ekhumoro Oct 10 '16 at 14:46
  • on ubuntu 16.04 and python 2.7.12 the 'open' button from the file dialog still opens the folder instead of adding its content to the list :/ – Michael P Mar 14 '17 at 17:06
  • @MichaelP. All my answer does is reimplement `accept()` and call the base-class method. If you want different behaviour, you need to re-write `accept()` accordingly. – ekhumoro Mar 14 '17 at 20:06
  • Sorry I was weird :) The 6 year old answer targets on how to select folders in a filedialog. So the complete answer is (of course!) a combination of yours and @panofish question. – Michael P Mar 15 '17 at 09:10