PDA

View Full Version : QSortFilterPoxyModel not filtering



ayanda83
6th November 2016, 14:55
Hi there, I have a QListView that displays pdf files from a Directory. To achieve this, I linked the QListView to the QFileSystemModel. My problem is that I need to be able to search for a file in the QListView using a pattern string, so I employed the use of a QSortFilterProxyModel. The QSortFilterProxyModel works fine except that it doesn't filter when I search for a particular file. Please see my code below.

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);

ui->listView_Main->setFlow(QListView::TopToBottom);
ui->listView_Main->setViewMode(QListView::ListMode);
ui->listView_Main->setWrapping(true);
ui->listView_Main->setResizeMode(QListView::Adjust);
ui->listView_Main->setUniformItemSizes(true);

QString root_path = "C:/Users/C5248134/Desktop/Projects/build-Ithala-Desktop_Qt_5_7_0_MSVC2015_64bit-Debug/Documents/";

proxyModel = new QSortFilterProxyModel(this);

f_model = new QFileSystemModel(this);
f_model->setFilter(QDir::Files);

proxyModel->setSourceModel(f_model);
proxyModel->setFilterRole(Qt::DisplayRole | Qt::DecorationRole);

if(f_model->rootDirectory().exists())
qDebug() << "Dir Found" <<endl;
else
qDebug() << "Dir not found" <<endl;

ui->listView_Main->setModel(proxyModel);
ui->listView_Main->setRootIndex(proxyModel->mapFromSource(f_model->setRootPath(root_path)));
}

Search button clicked slot.

void MainWindow::on_btnSearch_clicked()
{
QString patternStr = ui->leSearch->text();
QFileInfoList fileInfoObj = f_model->rootDirectory().entryInfoList();

proxyModel->setFilterFixedString(patternStr);
//ui->listView_Main->setRootIndex();
}
When I type-in a search string and then click on the search button the entire QListView goes blank. Please see screenshots of how my app looks before and after I search for a file.
Before12204 After12205

anda_skoa
6th November 2016, 16:01
If you look at your filter role definition, you will see that you are effectively filtering on Qt::DecorationRole as Qt::DisplayRole is 0.

And the decoration is the icon, which won't match any string.

You might want to filter on the DisplayRole or the FileNameRole

Cheers,
_

ayanda83
6th November 2016, 18:11
You might want to filter on the DisplayRole or the FileNameRole
_

I tried that and it didn't work. According to the documentation, the role is by default Qt::DisplayRole

anda_skoa
6th November 2016, 19:42
I tried that and it didn't work.

Tried with one of the other filter methods?


According to the documentation, the role is by default Qt::DisplayRole
But you set it to DecorationRole, which is not a string.

Cheers,
_

ayanda83
7th November 2016, 05:39
Tried with one of the other filter methods?


But you set it to DecorationRole, which is not a string.

Cheers,
_

I set it to both DecorationRole and DisplayRole so that I can display both the file icon and the file name. I also tried to display the file name only by setting it to DisplayRole only and that didn't work either.

If you look at my slot below, is it suppose to do what I want it to do? Because I am not too sure.


void MainWindow::on_btnSearch_clicked()
{
QString patternStr = ui->leSearch->text();
proxyModel->setFilterFixedString(patternStr);
}

anda_skoa
7th November 2016, 08:34
I set it to both DecorationRole and DisplayRole so that I can display both the file icon and the file name.

No.
First, the filter role has obviously nothing to do with display.
Second, the filter role is only a single role.
Third, a binary OR between two non-flag values is seldomly a valid value.
Fourth, in you case you where lucky as one of the value is 0 so the result of the OR is the second value.

So no, you did not set both DecorationRole and DisplayRole, as this is impossible and by sheer luck you only set DecorationRole.



I also tried to display the file name only by setting it to DisplayRole only and that didn't work either.

And you also tried with FileNameRole?



If you look at my slot below, is it suppose to do what I want it to do? Because I am not too sure.


void MainWindow::on_btnSearch_clicked()
{
QString patternStr = ui->leSearch->text();
proxyModel->setFilterFixedString(patternStr);
}
Yes, that looks reasonable.

Cheers,
_

ayanda83
9th November 2016, 14:18
I set the display role to Qt::Display only and the program does filter certain strings. For example the string "TW-" is filtered perfectly fine but other strings don't filter or they crash the program. I am pretty sure the problem is with line 29 in my constructor but I am not really sure what I need to do there.