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

时间:2010-04-23 02:48:24

标签: c++ qt4

我想创建一个搜索字段来过滤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;
  }

这几乎就在那里。我正在研究的“故障”与对象的显示位置有关。目前,如果我应用与列表中第3项匹配的搜索,则前两行将呈现为空白。换句话说,它仍然为非匹配项呈现行。

3 个答案:

答案 0 :(得分:6)

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

这里需要的是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似乎会被重置。当我想出来时,我会更新。

答案 1 :(得分:3)

这适用于 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 :(得分:2)

适用于 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)));