0

I want to display a certain folder form my disk with PyQt5's QFileSystemModel and add a filter with LineEdit for searching. I applied the solution given here.

The filtering works fine and it displays my folder. Now I want to add a function that gives my the file path, when clicking on a file. I added self.get_file_path function and I connected it to QListView, which displays my model. The self.get_file_path function simply contains file = self.file_model.filePath(index).

When I click on a file, the program crashes and just gives me Process finished with exit code 139 (interrupted by signal 11: SIGSEGV). If I leave the filter out and set the Model to self.file_model instead of self.proxy_model, the function gives me the file path.

I use PyCharm and MacOS 12.6.

Below is the full code:

from PyQt5 import QtCore, QtWidgets

class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(Widget, self).__init__(parent)
        le = QtWidgets.QLineEdit(textChanged=self.on_textChanged)
        self.lv = QtWidgets.QListView()
        self.lv.clicked.connect(self.get_file_path)

        self._dirpath = "path/to/folder"

        self.file_model = QtWidgets.QFileSystemModel()
        self.file_model.setRootPath(QtCore.QDir.rootPath())
        self.file_model.setFilter(QtCore.QDir.NoDotAndDotDot
            | QtCore.QDir.AllEntries
            | QtCore.QDir.Dirs
            | QtCore.QDir.Files)
        self.proxy_model = QtCore.QSortFilterProxyModel(
            recursiveFilteringEnabled=True,
            filterRole=QtWidgets.QFileSystemModel.FileNameRole)
        self.proxy_model.setSourceModel(self.file_model)
        self.lv.setModel(self.proxy_model)
        self.adjust_root_index()

        lay = QtWidgets.QVBoxLayout(self)
        lay.addWidget(le)
        lay.addWidget(self.lv)

    @QtCore.pyqtSlot(str)
    def on_textChanged(self, text):
        self.proxy_model.setFilterWildcard("*{}*".format(text))
        self.adjust_root_index()

    def adjust_root_index(self):
        root_index = self.file_model.index(self._dirpath)
        proxy_index = self.proxy_model.mapFromSource(root_index)
        self.lv.setRootIndex(proxy_index)

    def get_file_path(self, index):
        file = self.file_model.filePath(index)
        print(file)

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())
Mazze
  • 383
  • 3
  • 13
  • 1
    The `index` is that of the model of the view, which is the proxy, you cannot use it with the file model. Change to `file = self.file_model.filePath(self.proxy_model.mapToSource(index))` – musicamante Nov 15 '22 at 20:31
  • perfect, thanks! Do you also know, how I can rename files? I tried it with `self.lv.model().sourceModel().setData(self.proxy_model.mapToSource(index), newFile)`. I also added `self.file_model.setReadOnly(False)` – Mazze Nov 15 '22 at 21:28
  • That should theoretically work, so either the user doesn't have permission for that path, or the index wasn't valid. I suggest you to investigate and eventually create a new question with a related [mre]. – musicamante Nov 16 '22 at 01:44

0 Answers0