How to filter QListView that contains with QSortFilterProxyModel?
-
Hello all.
I have list of my own data type in class subclassed from QAbstreactListModel, I set this source to QSortFilterProxyModel on order to filter it. but I display the items in list view with delegate's paint method.
how can I filter this data? each of my object contains an pixmap, and QStrings(name, last name,etc.) and I paint this data on list view next to each other in each row.
i tried this.
@
proxy = new QSortFilterProxyModel;
proxy->setSourceModel(model);
listView->setModel(proxy);
listView->setItemDelegate(delegate);searchLine = new QLineEdit;
connect(searchLine,SIGNAL(textChanged(QString)),this,SLOT(onNewFilterText(QString)));void onNewFilterTExt(QString filter)
{
proxy->setDynamicSortFilter(true);
proxy->setFilterFixedString(filter);
}
@but when I type even 1 character, the view gets empty. what is wrong and how can I fix it?
thank you! -
the posted code of yours should work.
The default implementation of QSortFilterProxyModel filters all columns (using the DisplayRole) of your source model.The only thing that comes to my mind is that you type in lower-case text but the data is upper-case? By default QSortFilterProxyModel is case-sensitive (see QSortFilterProxyModel::setFilterCaseSensitivity())
-
I'm doing this.
@
void MainWindow::onNewFilterText(QString filter)
{
QList<Connection> searchDataList;
foreach (Connection conn, model->getData())
{
if(conn.getName().contains(filter,Qt::CaseInsensitive)
||conn.getProductName().contains(filter,Qt::CaseInsensitive)||
conn.getOS().contains(filter,Qt::CaseInsensitive)||
conn.getOS().contains(filter,Qt::CaseInsensitive)||
conn.getProtocol().contains(filter,Qt::CaseInsensitive))
{
searchDataList.append(conn);
}
}
}
@
but how to set this list to the proxy? -
[quote author="tokafr" date="1421828913"]I'm doing this.
@
void MainWindow::onNewFilterText(QString filter)
{
QList<Connection> searchDataList;
foreach (Connection conn, model->getData())
{
if(conn.getName().contains(filter,Qt::CaseInsensitive)
||conn.getProductName().contains(filter,Qt::CaseInsensitive)||
conn.getOS().contains(filter,Qt::CaseInsensitive)||
conn.getOS().contains(filter,Qt::CaseInsensitive)||
conn.getProtocol().contains(filter,Qt::CaseInsensitive))
{
searchDataList.append(conn);
}
}
}
@
but how to set this list to the proxy?[/quote]this is the wrong approach. QSortFitlerProxyModel already provides all you need.
Please post the data() method of your source model.
-
@
QVariant Model::data(const QModelIndex &index, int role) const
{QVariant data;
if(!index.isValid())
{
return QVariant();
}if(index.row() < 0 || index.row() >= dataList.size())
{
return QVariant();
}if(role == Qt::DecorationRole || role == Qt::DisplayRole)
{data.setValue(dataList.at(index.row())); return data;
}
return QVariant();
}
@ -
@
if(role == Qt::DecorationRole || role == Qt::DisplayRole)
{
data.setValue(dataList.at(index.row()));
return data;
}
@
whats the type of the items contained in "dataList"? I guess they are not of type QString. Thats the reason why it doesn't work because it tried to find your entered text inside an empty string.You need to return a string representation for Qt::DisplayRole, because QSortFilterProxyModel uses this role by default for filtering.
Or you introduce a new item role and tell QSortFilterProxyModel to do the filtering on this role:
@
QVariant Model::data(const QModelIndex &index, int role) const
{QVariant data; if(!index.isValid()) { return QVariant(); } if(index.row() < 0 || index.row() >= dataList.size()) { return QVariant(); } if(role == Qt::DecorationRole || role == Qt::DisplayRole) { data.setValue(dataList.at(index.row())); return data; } else if( role == Qt::UserRole ) return dataList.at(index.row())->toString(); //<--- adapt this to return QString return QVariant(); }
@
and then this on your proxy model:
@
proxy->setFilterRole( Qt::UserRole );
@