2

In my application I have a QTreeview. I have a folder named "test" that contains many subfolders. The treeview only shows the subfolders not the test forlder it self!

def create_treeview(self):
    self.treeView = QTreeView()
    self.treeView.setMinimumSize(QSize(250, 0))
    self.treeView.setMaximumSize(QSize(250, 16777215))
    self.treeView.setObjectName("treeView")

    self.dirModel = QFileSystemModel()
    self.dirModel.setRootPath(QDir.rootPath())
    self.dirModel.setFilter(QDir.NoDotAndDotDot | QDir.AllDirs)

    self.treeView.setModel(self.dirModel)
    self.treeView.setRootIndex(self.dirModel.index("/home/data/test"))
    self.treeView.setHeaderHidden(True)
    self.treeView.clicked.connect(self.tree_click)
    return self.treeView
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
Rafa
  • 467
  • 4
  • 18

1 Answers1

3

The rootIndex of the QTreeView is hidden so it is not shown. One possible solution is to pass the parent of the path and use a QSortFilterProxyModel to hide the other directories and files.

import os

from PyQt5.QtCore import pyqtSlot, QDir, QModelIndex, QSize, QSortFilterProxyModel
from PyQt5.QtWidgets import QApplication, QFileSystemModel, QMainWindow, QTreeView


class ProxyModel(QSortFilterProxyModel):
    def __init__(self, parent=None):
        super().__init__(parent)
        self._root_path = ""

    def filterAcceptsRow(self, source_row, source_parent):
        source_model = self.sourceModel()
        if self._root_path and isinstance(source_model, QFileSystemModel):
            root_index = source_model.index(self._root_path).parent()
            if root_index == source_parent:
                index = source_model.index(source_row, 0, source_parent)
                return index.data(QFileSystemModel.FilePathRole) == self._root_path
        return True

    @property
    def root_path(self):
        return self._root_path

    @root_path.setter
    def root_path(self, p):
        self._root_path = p
        self.invalidateFilter()


class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.create_treeview()
        self.setCentralWidget(self.treeView)

    def create_treeview(self):

        path = "/home/data/test"

        self.treeView = QTreeView()
        self.treeView.setMinimumSize(QSize(250, 0))
        self.treeView.setMaximumSize(QSize(250, 16777215))
        self.treeView.setObjectName("treeView")

        self.dirModel = QFileSystemModel()
        self.dirModel.setRootPath(QDir.rootPath())
        self.dirModel.setFilter(QDir.NoDotAndDotDot | QDir.AllDirs)

        root_index = self.dirModel.index(path).parent()

        self.proxy = ProxyModel(self.dirModel)
        self.proxy.setSourceModel(self.dirModel)
        self.proxy.root_path = path

        self.treeView.setModel(self.proxy)

        proxy_root_index = self.proxy.mapFromSource(root_index)
        self.treeView.setRootIndex(proxy_root_index)

        self.treeView.setHeaderHidden(True)
        self.treeView.clicked.connect(self.tree_click)

    @pyqtSlot(QModelIndex)
    def tree_click(self, index):
        ix = self.proxy.mapToSource(index)
        print(
            ix.data(QFileSystemModel.FilePathRole),
            ix.data(QFileSystemModel.FileNameRole),
        )


if __name__ == "__main__":
    import sys

    app = QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • i've used `path = "c:/windows/system32/drivers/etc"` in your example and i'll get this [output](https://dl.dropboxusercontent.com/s/2g3bq7p5bn1hbn1/python_2019-11-12_00-54-51.png), any idea what's wrong? – BPL Nov 11 '19 at 23:55
  • @BPL remove `self.dirModel.setFilter(QDir.NoDotAndDotDot | QDir.AllDirs)` – eyllanesc Nov 11 '19 at 23:59
  • @eyllanesc Thanks but no luck, same output than my previous comment :/ – BPL Nov 12 '19 at 00:03
  • @BPL Try simpler paths, analyze the filterAcceptsRow information since in windows there is always the problem of path separation: "/", "\\", etc. – eyllanesc Nov 12 '19 at 00:04
  • @BPL what is the output of `print(QDir.rootPath())`? – eyllanesc Nov 12 '19 at 00:07
  • @eyllanesc `print(repr(QDir.rootPath()))` gave me `'C:/'`. I've tried `self.treeView.setCurrentIndex(proxy_root_index)` after line `self.treeView.setRootIndex(proxy_root_index)` but unfortunately didn't help – BPL Nov 12 '19 at 00:10
  • @BPL `c:/windows/system32/drivers/etc` or `C:/windows/system32/drivers/etc`? – eyllanesc Nov 12 '19 at 00:11
  • @eyllanesc Tried with both and the output will be "wrong" as posted in my previous screenshot. It's funny, qt is multiplatform so i don't understand why your code would fail here... – BPL Nov 12 '19 at 00:13
  • @BPL I think that the path is the one that generates the problem, try the following code where you must select the etc directory: https://gist.github.com/eyllanesc/e8623026aa183aa7230c8ab4f54e8a82 – eyllanesc Nov 12 '19 at 00:18