PDA

View Full Version : QSortFilterProxyModel not filtering properly



freemind
23rd July 2010, 20:19
Hi,

When i try to filter items with a QSortFilterProxyModel it doesn't work properly.I've been trying to solve this problem, but i can't figure out what i am missing.



proxyModel = new QSortFilterProxyModel(this);
proxyModel->setDynamicSortFilter(true);
proxyModel->setSourceModel(&m_filesystem);
m_ui.v_files->setModel(proxyModel); //QListView


and then just doing this should work, i guess:

proxyModel->setFilterFixedString(m_toolbarSearch->text());

But it doesn't, it seems it's just filtering the first element.
Any ideas?

Thanks

armonge
23rd July 2010, 22:33
Try setting filterKeyColumn (http://doc.qt.nokia.com/4.6/qsortfilterproxymodel.html#filterKeyColumn-prop)

freemind
24th July 2010, 00:24
I used this way:

proxyModel->setFilterKeyColumn(-1);

But the same problem persists.

armonge
24th July 2010, 03:27
Why don't you try giving some sample data and the expected result?

freemind
24th July 2010, 15:01
Why don't you try giving some sample data and the expected result?

Fair enough. The application i'm making is a file browser, so imagine a directory with the folders' names from A to Z. If i filter for 'A' (the first element) it hides the others and only shows the folder 'A', but if i try to filter for 'B' or other, i get no results.

armonge
24th July 2010, 22:32
For hierarchical models, the filter is applied recursively to all children. If a parent item doesn't match the filter, none of its children will be shown.
http://doc.qt.nokia.com/4.6/qsortfilterproxymodel.html

freemind
25th July 2010, 15:24
But i'm only showing one "folder level" at time... so the parent/children iissue you described shouldn't affect it.

ChrisW67
26th July 2010, 00:02
Fair enough. The application i'm making is a file browser, so imagine a directory with the folders' names from A to Z. If i filter for 'A' (the first element) it hides the others and only shows the folder 'A', but if i try to filter for 'B' or other, i get no results.
You are going to have to post a small compilable example of what you are actually doing.

freemind
7th August 2010, 21:44
Hi again,

app.cpp


#include "app.hpp"

App::App(QWidget * p_parent): QMainWindow(p_parent)
{
m_ui.setupUi(this);

model = new QFileSystemModel(this);
model->setRootPath(QDir::currentPath());
proxyModel = new QSortFilterProxyModel(this);
proxyModel->setDynamicSortFilter(true);
proxyModel->setSourceModel(model);
proxyModel->mapFromSource(model->index(QDir::currentPath()));

m_ui.listView->setModel(proxyModel);

m_ui.listView->setRootIndex(proxyModel->mapFromSource(model->index(QDir::currentPath())));

connect(m_ui.lineEdit, SIGNAL(textChanged(QString)), this, SLOT(filter(QString)));

}

void App::filter(QString pattern_filter)
{
proxyModel->setFilterFixedString(pattern_filter);
}


app.hpp:


#ifndef _HPP_APP
#define _HPP_APP

#include <QFileSystemModel>
#include <QMainWindow>
#include <QSortFilterProxyModel>
#include <QFileSystemModel>
#include <QDir>
#include <QTextStream>
#include "ui_app.h"


class App : public QMainWindow
{
Q_OBJECT

public:
App(QWidget * p_parent = 0);

public slots:
void filter(QString );

private:
Ui::MainWindow m_ui;
QSortFilterProxyModel *proxyModel;
QFileSystemModel *model;

};

#endif


ui_app.h:


/************************************************** ******************************
** Form generated from reading UI file 'app.ui'
**
** Created: Sat Aug 7 21:35:40 2010
** by: Qt User Interface Compiler version 4.6.2
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
************************************************** ******************************/

#ifndef UI_APP_H
#define UI_APP_H

#include <QtCore/QVariant>
#include <QtGui/QAction>
#include <QtGui/QApplication>
#include <QtGui/QButtonGroup>
#include <QtGui/QHeaderView>
#include <QtGui/QLineEdit>
#include <QtGui/QListView>
#include <QtGui/QMainWindow>
#include <QtGui/QMenuBar>
#include <QtGui/QStatusBar>
#include <QtGui/QToolBar>
#include <QtGui/QVBoxLayout>
#include <QtGui/QWidget>

QT_BEGIN_NAMESPACE

class Ui_MainWindow
{
public:
QWidget *centralwidget;
QVBoxLayout *verticalLayout;
QLineEdit *lineEdit;
QListView *listView;
QMenuBar *menubar;
QStatusBar *statusbar;
QToolBar *toolBar;

void setupUi(QMainWindow *MainWindow)
{
if (MainWindow->objectName().isEmpty())
MainWindow->setObjectName(QString::fromUtf8("MainWindow"));
MainWindow->resize(686, 402);
centralwidget = new QWidget(MainWindow);
centralwidget->setObjectName(QString::fromUtf8("centralwidget"));
verticalLayout = new QVBoxLayout(centralwidget);
verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));
lineEdit = new QLineEdit(centralwidget);
lineEdit->setObjectName(QString::fromUtf8("lineEdit"));

verticalLayout->addWidget(lineEdit);

listView = new QListView(centralwidget);
listView->setObjectName(QString::fromUtf8("listView"));

verticalLayout->addWidget(listView);

MainWindow->setCentralWidget(centralwidget);
menubar = new QMenuBar(MainWindow);
menubar->setObjectName(QString::fromUtf8("menubar"));
menubar->setGeometry(QRect(0, 0, 686, 25));
MainWindow->setMenuBar(menubar);
statusbar = new QStatusBar(MainWindow);
statusbar->setObjectName(QString::fromUtf8("statusbar"));
MainWindow->setStatusBar(statusbar);
toolBar = new QToolBar(MainWindow);
toolBar->setObjectName(QString::fromUtf8("toolBar"));
MainWindow->addToolBar(Qt::TopToolBarArea, toolBar);

retranslateUi(MainWindow);

QMetaObject::connectSlotsByName(MainWindow);
} // setupUi

void retranslateUi(QMainWindow *MainWindow)
{
MainWindow->setWindowTitle(QApplication::translate("MainWindow", "MainWindow", 0, QApplication::UnicodeUTF8));
toolBar->setWindowTitle(QApplication::translate("MainWindow", "toolBar", 0, QApplication::UnicodeUTF8));
} // retranslateUi

};

namespace Ui {
class MainWindow: public Ui_MainWindow {};
} // namespace Ui

QT_END_NAMESPACE

#endif // UI_APP_H


main.cpp


#include <QtGui/QApplication>
#include "app.hpp"


int main(int argc, char ** argv)
{
QApplication app(argc, argv);
App myapp;
myapp.show();

return app.exec();
}

ChrisW67
8th August 2010, 01:23
Your QFileSystemModel is the entire filesystem, not just the sub-tree you are displaying. The filter is applied to the top element in the model, which on Linux is just the root (not sure on Windows), decides it doesn't match and excludes everything from the model.

You should look at QFileSystemModel::nameFilters(), QFileSystemModel::nameFilterDisables, and QFileSystemModel::setFilter() to achieve your filtering.