Создание поля поиска QLineEdit для элементов, отображаемых в QListView - PullRequest
6 голосов
/ 23 апреля 2010

Я хочу создать поле поиска, которое фильтрует элементы, показанные в QListView. Обычно пользователь может ввести «foo», и отображаются только элементы с «foo» в DisplayRole.

У меня уже есть несколько идей о том, как это сделать, но я решил спросить тех, кто опытнее меня.

Моя идея состоит в том, чтобы использовать некоторые сигналы и слоты для установки фильтра в модели QAbstractItem и запуска обновления () в QListView.

Есть ли в QListView вспомогательные методы для фильтрации, которые я мог пропустить?

Есть ли канонический способ справиться с этим, с которым я не сталкивался?

1012 * редактировать *

Текущий прогресс.

Я создал публичный слот с именем «updateFilter (QString)» в моем подклассе QFileSystemModel. Тогда я

connect(myQLineEditSearch, SIGNAL(textChanged(QString)), 
        myQFileSysModel, SLOT(updateFilter(QString)));

Это устанавливает фильтр, затем в моем методе QFileSystemModel :: data (...), у меня есть:

  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-му элементу в списке, только первые две строки отображаются как пустые. Другими словами, он по-прежнему отображает строки для несопоставленных элементов.

Ответы [ 3 ]

6 голосов
/ 23 апреля 2010

Отвечая на мой вопрос для справки.

Похоже, что здесь необходим 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, кажется, сбрасывается при вводе строки поиска. Я обновлю, когда выясню это.

3 голосов
/ 23 апреля 2010

Это будет работать для 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() );
2 голосов
/ 01 сентября 2015

Другое решение, которое работает для QListWidget :

void SpeciePropertiesListWidget::filter(QString filter_string)
{
  hide_all();
  QList<QListWidgetItem*> matches ( m_list->findItems(filter_string, Qt::MatchFlag::MatchContains) );
  for(QListWidgetItem* item : matches)
    item->setHidden(false);
}

void SpeciePropertiesListWidget::hide_all()
{
  for(int row(0); row < m_list->count(); row++ )
    m_list->item(row)->setHidden(true);
}

А затем подключите QLineEdit:

QLineEdit * m_filter_le = new QLineEdit(this);
SpeciePropertiesListWidget * list_widget = new SpeciePropertiesListWidget(this)
connect(m_filter_le, SIGNAL(textEdited(QString)), list_widget, SLOT(refresh_filter(QString)));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...