C++ 为QListView中显示的项目创建QLineEdit搜索字段
我想创建一个搜索字段来过滤QListView中显示的项目。基本上,用户可以输入“foo”,并且只显示DisplayRole中带有“foo”的项目 我已经有了一些关于如何做到这一点的想法,但我想我会问那些比我更有经验的人 我的想法是使用一些信号和插槽在QAbstractItem模型中设置一个过滤器,并在QListView中触发一个update() QListView中是否有我可能遗漏的筛选帮助程序方法 有没有一种我从未遇到过的规范的处理方法 编辑 目前的进展 我在QFileSystemModel子类中创建了一个名为“updateFilter(QString)”的公共槽。然后我C++ 为QListView中显示的项目创建QLineEdit搜索字段,c++,qt4,C++,Qt4,我想创建一个搜索字段来过滤QListView中显示的项目。基本上,用户可以输入“foo”,并且只显示DisplayRole中带有“foo”的项目 我已经有了一些关于如何做到这一点的想法,但我想我会问那些比我更有经验的人 我的想法是使用一些信号和插槽在QAbstractItem模型中设置一个过滤器,并在QListView中触发一个update() QListView中是否有我可能遗漏的筛选帮助程序方法 有没有一种我从未遇到过的规范的处理方法 编辑 目前的进展 我在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;
}
就快到了。我正在处理的“小故障”与对象的显示位置有关。当前,如果应用与列表中第三项匹配的搜索,则只有前两行显示为空白。换句话说,它仍然呈现不匹配项的行。这适用于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)));