簡體   English   中英

為QListView中顯示的項創建QLineEdit搜索字段

[英]Creating a QLineEdit search field for items displayed in a QListView

我想創建一個搜索字段來過濾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項匹配的搜索,則前兩行將呈現為空白。 換句話說,它仍然為非匹配項呈現行。

回答我自己的問題以供參考。

看起來這里需要的是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() );

另一個適用於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)));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM