[Solved] - Working with QSortFilterModel QFileSystemModel and QTableView.
-
I have a custom file dialog that consists of a tableView which uses a QSortFilterProxyModel whose source model is QFileSystemModel, The tableView displays all the files for a particular path/folder, on top of the tableView there is a lineEdit that is used for filtering.
So as per the use case the tableView displays only the matched content from the filter string. The issue is when the content does not match the item the view does not display anything ( works perfect) but when I use backspace and edit the filterString the model is reset to the root folder i.e C: drive D: drive E: drive.
For eg.
QFileSystemModel rootPath : E:\Test (tableView shows all the files in E:\Test
FilterString: 10 (matched) : tableView filters and displays all the rows that contain 10
FilterString 100: (not matched) : tableView does not display anything
FilterString 10 : Press BackSpace and edit the FilterString - tableView falls back to Root Folder and displays
C: drive D: drive E: drive. instead it should load files from E:Test that contains 10.I figured out if there is an invalid QModelIndex() in filterAcceptsRow() of QSortFilterProxyModel , I return false, which inturn resets the model back to root folder.
@bool TestProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{
if(filterKeyColumn() >= 0)
{
if(m_fileSystemModel)
{
if(filterMatchSubItem(sourceModel()->index(source_row, filterKeyColumn(), source_parent)))
return true;
}
else
return filterMatchSubItem(sourceModel()->index(source_row, filterKeyColumn(), source_parent));
}
else
{
qint32 idx = 0;
bool filterMatch = false;
while(idx < sourceModel()->columnCount(source_parent) && !filterMatch)
{
filterMatch = filterMatchSubItem(sourceModel()->index(source_row, idx, source_parent));
idx++;
}if(m_fileSystemModel) { if(filterMatch) return true; } else return filterMatch; }
if(!source_parent.isValid())
{
return false;
}return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
}
@@bool LiSortFilterProxyModel::filterMatchSubItem(const QModelIndex &source_parent) const
{
if (source_parent.isValid())
{
QString itemValue = sourceModel()->data(source_parent, Qt::DisplayRole).toString();if(m_fileSystemModel) { QFileInfo fi(itemValue); if(fi.isFile() && !fi.completeSuffix().isEmpty()) { if(fi.baseName().contains(filterRegExp())) return true; } else { if (itemValue.contains(filterRegExp())) return true; } } else { if (itemValue.contains(filterRegExp())) return true; } if (sourceModel()->hasChildren(source_parent)) { for (int i = 0; i < sourceModel()->rowCount(source_parent); i++) { qint32 idx = 0; bool filterMatch = false; while(idx < sourceModel()->columnCount(source_parent) && !filterMatch) { filterMatch = filterMatchSubItem(sourceModel()->index(i, idx, source_parent)); idx++; } if(filterMatch) return true; } } } return false;
}@
What am I missing !
P.S: Do I need the set the Root Index of the TableView ?
like m_tableView->setRootIndex(indexOfPathFromFileSystemModel); -
Hi,
Could you post a minimal sample application somewhere e.g. github to test this ?