Я хочу создать поле поиска, которое фильтрует объекты, показанные в QListView. В основном пользователь мог ввести в "нечто", и только объекты с "нечто" в DisplayRole показывают.
У меня уже есть несколько идей о том, как сделать это, но думал, что я спрошу более опытных, чем я.
Моя идея состояла бы в том, чтобы использовать некоторые сигналы и слоты, чтобы установить фильтр в модели QAbstractItem и инициировать обновление () в QListView.
Есть ли какие-либо вспомогательные методы в QListView для фильтрации, которую я, возможно, пропустил?
Существует ли канонический способ обработать это, я не натыкался?
править
Текущий прогресс.
Я создал общедоступный слот, названный "updateFilter (QString)" в моем подклассе QFileSystemModel. Затем я
connect(myQLineEditSearch, SIGNAL(textChanged(QString)),
myQFileSysModel, SLOT(updateFilter(QString)));
Это устанавливает фильтр, затем в моем QFileSystemModel:: данные (...) метод, я имею:
void ComponentModel::updateFilter(QString filter)
{
_filter = filter;
emit layoutChanged();
}
QVariant ComponentModel::data(const QModelIndex &index, int role) const
{
QVariant result;
// if our search filter term is set and the item does not match,
// do not display item data. Searches are case insensitive
if (!_filter.isEmpty() &&
!QFileSystemModel::data(index, Qt::DisplayRole)
.toString().toLower().contains(_filter.toLower()))
{
return result;
}
result = QFileSystemModel::data(index, role);
return result;
}
Это почти там. "Незначительный сбой" я продолжаю работать, имеет отношение, где объект отображен. В настоящее время, если я применяю поиск, который соответствует 3-му объекту в списке, только первые две строки представляются как пробел. Другими словами, это все еще представляет строки для неподобранных объектов.
Отвечая на мой собственный вопрос для справки.
Похоже, здесь нужна модель QSortFilterProxyModel.
Код выглядит примерно так:
QListView *myview = new QListView(this);
MyModel *model = new MyModel(this);
QSortFilterProxyModel *proxy = new QSortFilterProxyModel(this);
proxy->setSourceModel(model);
myview->setModel(proxy);
myview->setRootIndex(proxy->mapFromSource(model->index(model->rootPath()));
connect(filterLineEdit, SIGNAL(textChanged(QString)),
proxy, SLOT(setFilterFixedString(QString)));
Единственная проблема, которую я вижу в этом, - это то, что rootIndex, кажется, сбрасывается, когда вы вводите строку поиска. Я обновлюсь, когда выясню это.
Это будет работать для QListWidget ...
Этот метод сохраняет все найденные элементы в QList, из которого вы можете позже их прочитать (например, чтобы показать их в том же или новом QListView):
void search_for_string( QString search_str )
{
QList<QListWidgetItem*> my_found_items;
for( int i = 0; i < my_list->count(); i++ )
{
QListWidgetItem* current = my_list->item( i );
if( current->text().contains( search_str ) )
{
my_found_items.append( current );
}
}
}
И при нажатии на «Поиск» или как-то еще, вы называете это так:
search_for_string( my_line_edit->text() );