Solved QTreeView QFileSystemModel and QSortFilterProxyModel question
-
I have a simple QTreeView displaying a QSortFilterProxyModel with a source model of QFileSystemModel
For the proxy model I have setRecursiveFilteringEnabled to True, setAutoAcceptChildRows to True and it is doing a case insensitive search viasetFilterRegularExpression='.*{}.*'.format(search)
Which does return some search results, but not all and I'm assuming its because the parent folders are being hidden because they do not match the expression. However looking thru the source for QSortFilterProxyModel It seems like it should auto accept parents if the child is accepted, Is that a misunderstanding?
-
Well I have the desired output however it is terribly slow with large directories, is there anyway I can improve upon this?
class DFilterProxyModel(QSortFilterProxyModel): def filterAcceptsRow(self, source_row: int, source_parent: QModelIndex) -> bool: filter_exp = self.filterRegularExpression() filter_column = self.filterKeyColumn() if not filter_exp: return True if filter_column == -1: column_count = self.sourceModel().columnCount(source_parent) for column in range(column_count): source_idx = self.sourceModel().index(source_row, column, source_parent) key = str(self.sourceModel().data(source_idx, self.filterRole())) filter_data = filter_exp.match(key) if filter_data.hasMatch(): return True return False source_idx = self.sourceModel().index(source_row, filter_column, source_parent) if not source_idx.isValid(): return True key = str(self.sourceModel().data(source_idx, self.filterRole())) filter_data = filter_exp.match(key) if filter_data.hasMatch(): return True else: if self.sourceModel().canFetchMore(source_idx): print(self.sourceModel().data(source_idx, self.filterRole())) self.sourceModel().fetchMore(source_idx) return filter_data.hasMatch()
-
@Strilles
Have you checked your usage of{}
? I don't know here, but they are used for "match-counts" in, say.{2,4}
. Did you try escaping them,\{\}
? -
Hi,
@Strilles said in QTreeView QFileSystemModel and QSortFilterProxyModel question:
I'm assuming its because the parent folders are being hidden because they do not match the expression.
I had the same issue. Parent folders where hidden, that did not match filter expression.
I ended up writing my own model for filesystem handling.
-
@JonB
with the {} I am usingstr.format(*args, **kwargs)
which the {} is just a place holder for the search phrase.
In my case
setFilterRegularExpression('.*{}.*'.format(search))
becomes
setFilterRegularExpression('.*search.*')
Though I could be wrong with the usage of str.format
-
@django-Reinhard
I might just have to re-implement the proxy-model or the dir model.
After having looked at your source, I decided to dig into the FileSystemModel itself. It seems my problem may be with the fact that in sub directories nothing "exists" to the proxy model until the model loads it in because the DirModel only loads in what is necessary. -
@Strilles said in QTreeView QFileSystemModel and QSortFilterProxyModel question:
setFilterRegularExpression('.*{}.*'.format(search))
May well have nothing to do with your current issue, but be aware this will break if
search
string has any of a number of literal punctuation characters in it. -
@JonB
Noted, I will refactor that portion to prevent those cases. Thank you for assistance, I think I have a way forward just need to implement it. -
@Strilles said in QTreeView QFileSystemModel and QSortFilterProxyModel question:
It seems my problem may be with the fact that in sub directories nothing "exists" to the proxy model until the model loads it in because the DirModel only loads in what is necessary.
Well, I created a "filedialog" as master-detail-view, where the Treeview contains directories only. Tableview is filled at selecting a directory from Treeview and Preview (PlainTextEdit) shows the data after a file from Tableview has been selected (using event handlers from Qt).
-
Well I have the desired output however it is terribly slow with large directories, is there anyway I can improve upon this?
class DFilterProxyModel(QSortFilterProxyModel): def filterAcceptsRow(self, source_row: int, source_parent: QModelIndex) -> bool: filter_exp = self.filterRegularExpression() filter_column = self.filterKeyColumn() if not filter_exp: return True if filter_column == -1: column_count = self.sourceModel().columnCount(source_parent) for column in range(column_count): source_idx = self.sourceModel().index(source_row, column, source_parent) key = str(self.sourceModel().data(source_idx, self.filterRole())) filter_data = filter_exp.match(key) if filter_data.hasMatch(): return True return False source_idx = self.sourceModel().index(source_row, filter_column, source_parent) if not source_idx.isValid(): return True key = str(self.sourceModel().data(source_idx, self.filterRole())) filter_data = filter_exp.match(key) if filter_data.hasMatch(): return True else: if self.sourceModel().canFetchMore(source_idx): print(self.sourceModel().data(source_idx, self.filterRole())) self.sourceModel().fetchMore(source_idx) return filter_data.hasMatch()