-1

I have a QFileDialog and I want to filter out all paths that are not in ~/Documents.

Current have

from PyQt5 import QtCore
import os

...
dialog = QtWidgets.QFileDialog(...)
dialog.setDirectory(os.path.expanduser("~/Documents"))
dialog.setProxyModel(MyFilter())
selectedPath = dialog.exec_()

...

class MyFilter(QtCore.QSortFilterProxyModel):

   def filterAcceptsRow(self, p_int, QModelIndex):
       sourceModel = self.sourceModel()
       index = sourceModel.index(p_int, 0,QModelIndex)
       path = sourceModel.filePath(index)
       return self._inside_documents_or_is_ancestor(path)

   def _inside_documents_or_is_ancestor(self, path):
        docpath = os.path.expanduser("~/Documents")
        if path.startswith(docpath) or docpath.startswith(path):
            print True, path, docpath
            return True
        return False

It seems like none of the paths are being filtered since I can choose any file in my filesystem in the QFileDialog.

I'm not sure about details of filterAcceptsRow(), but it seems that if I reject a directory, its subdirectories will not be considered, that's why I'm accepting those paths that ancestors of my desired path.

I am running pyqt 5.1 and python 2.7.5

mingxiao
  • 1,712
  • 4
  • 21
  • 33
  • Have you checked with print if the return value is OK in those cases when you select such a path? – László Papp Dec 31 '13 at 01:01
  • updated to more closely reflect my scenario. Confused as to the affects of filterAcceptsRow(), if I use a blanket "return False" I can still see my filesystem and select items just fine – mingxiao Dec 31 '13 at 01:12
  • I do not see in your code that you are actually using that filter anywhere for starter. – László Papp Dec 31 '13 at 01:16
  • ok added, it was in the original code I ran – mingxiao Dec 31 '13 at 01:19
  • according to http://qt-project.org/doc/qt-4.8/qsortfilterproxymodel.html#filterAcceptsRow , return True if you want the item to be included. Edited code, but I'm setting the proxy model and calling .exec_() – mingxiao Dec 31 '13 at 01:49
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/44196/discussion-between-mingxiao-and-laszlo-papp) – mingxiao Dec 31 '13 at 01:55
  • Is this still unresolved one year later?? – László Papp Dec 21 '14 at 10:43

1 Answers1

0

Based on the comment discussion, I think your condition is simply wrong.

You are using os.path.startswith which will include all the subfolders as well, naturally. Your question writes those would need to be kept. Naturally, your condition is incorrect respectively.

You should write something like this instead:

if os.path.dirname(path) == docpath:
    return False

Please note that you also returned True for your condition which inherently means, nothing will really get filtered out as you would like to have it.

Furthermore, I would consider this as a usability issue eventually in your user interface design. Users would not be able to browse into that folder unless they start typing the whole path. A much better UX approach (in my opinion for sure) would be to actually allow them to browse, and warn them later if they wish to select a file from that particular folder.

László Papp
  • 51,870
  • 39
  • 111
  • 135