2010-04-23 22 views
6

'da görüntülenen öğeler için bir QLineEdit arama alanı oluşturma QListView'da gösterilen öğeleri filtreleyen bir arama alanı oluşturmak istiyorum. Temel olarak kullanıcı "foo" yazabilir ve DisplayRole'da sadece "foo" olan öğeler gösterilir.QListView

Zaten bu nasıl yapılacağı konusunda birkaç fikir var, ama QAbstractItem modelinde filtre ayarlandığını bazı sinyaller ve yuvaları kullanmak olacaktır I.

Benim fikirden daha tecrübeli olanlar isteyecektim ve QListView'da bir güncelleme() tetikleyin.

Filtreleme için QListView'da herhangi bir yardımcı yöntem var mı?

Karşılaştığım bu işin kurallı bir yolu var mı?

düzenlemek

Güncel ilerleme.

QFileSystemModel alt sınıfımda "updateFilter (QString)" adlı bir genel yuva oluşturdum. Sonra

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

Sonra bu benim QFileSystemModel içinde, filtre ayarlar :: verileri (...) yöntemi, var:

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

Bu neredeyse yoktur. Çalıştığım "aksaklık", nesnenin görüntülendiği yer ile ilgili. Şu anda, listedeki 3. öğeyle eşleşen bir arama uygularsam yalnızca ilk iki satır boş olarak görüntülenir. Başka bir deyişle, hala eşleşmeyen öğeler için satırlar oluşturur.

cevap

5

için kendi sorumu yanıtlayan referans.

Burada gerekenin bir QSortFilterProxyModel olduğu anlaşılıyor. Bunda görüyorum tek sorun rootIndex Bir arama dizesini girdiğinizde sıfırlamak almak gibi görünüyor olduğunu

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

:

kod şöyle görünür. Bunu anladığımda güncelleyeceğim.

3

Bu QListWidget için çalışacak ...

Bu yöntem daha sonra (örneğin aynı veya yeni QListView bunları gösterilmesi için) onları okuyabilir hangi bir QList içinde bulunan tüm öğeleri kaydeder:

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

ve "ara" ya da her türlü basıldığında, böyle diyoruz:

search_for_string(my_line_edit->text()); 
+1

Bu iyi görünüyor, ama aynı zamanda el ile arama butonuna tıklayarak kullanıcı bağımlı görünüyor ya da bunlardan bazıları.Qlistview'a canlı güncellemeler almaya çalışıyorum. Mevcut gelişmemi yansıtmak için yayınımı güncelledim. – jkyle

2

için çalışan bir başka çözüm QListWidget: o zaman

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

Ve QLineEdit bağlamak:

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