C++ 为QListView中显示的项目创建QLineEdit搜索字段

C++ 为QListView中显示的项目创建QLineEdit搜索字段,c++,qt4,C++,Qt4,我想创建一个搜索字段来过滤QListView中显示的项目。基本上,用户可以输入“foo”,并且只显示DisplayRole中带有“foo”的项目 我已经有了一些关于如何做到这一点的想法,但我想我会问那些比我更有经验的人 我的想法是使用一些信号和插槽在QAbstractItem模型中设置一个过滤器,并在QListView中触发一个update() QListView中是否有我可能遗漏的筛选帮助程序方法 有没有一种我从未遇到过的规范的处理方法 编辑 目前的进展 我在QFileSystemModel子

我想创建一个搜索字段来过滤QListView中显示的项目。基本上,用户可以输入“foo”,并且只显示DisplayRole中带有“foo”的项目

我已经有了一些关于如何做到这一点的想法,但我想我会问那些比我更有经验的人

我的想法是使用一些信号和插槽在QAbstractItem模型中设置一个过滤器,并在QListView中触发一个update()

QListView中是否有我可能遗漏的筛选帮助程序方法

有没有一种我从未遇到过的规范的处理方法

编辑

目前的进展

我在QFileSystemModel子类中创建了一个名为“updateFilter(QString)”的公共槽。然后我

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;
  }

就快到了。我正在处理的“小故障”与对象的显示位置有关。当前,如果应用与列表中第三项匹配的搜索,则只有前两行显示为空白。换句话说,它仍然呈现不匹配项的行。

这适用于QListWidget

此方法将所有找到的项保存在QList中,您可以稍后从中读取它们(例如,在相同或新的QListView中显示它们):


回答我自己的问题以供参考

看起来这里需要的是一个QSortFilterProxy模型

代码如下所示:

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的解决方案:

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);
}

这看起来不错,但也取决于用户手动单击搜索按钮或类似按钮。我正在尝试获取qlistview的实时更新。我已经更新了我的帖子,以反映我目前的进展。
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)));
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 * 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)));