2008-10-30 42 views
7

Tôi có một số QDirModel có thư mục hiện tại được đặt. Sau đó, tôi có một QListView được cho là để hiển thị các tập tin trong thư mục đó. Điều này hoạt động tốt.Sử dụng QSortFilterProxyModel với mô hình cây

Bây giờ tôi muốn giới hạn các tệp được hiển thị, vì vậy nó chỉ hiển thị các tệp png (tên tệp kết thúc bằng .png). Vấn đề là sử dụng một QSortFilterProxyModel và thiết lập regexp bộ lọc sẽ cố gắng để phù hợp với mỗi phụ huynh của các tập tin là tốt. Theo tài liệu:

Đối với các mô hình phân cấp, bộ lọc là áp dụng đệ quy cho tất cả trẻ em. Nếu mục cha không khớp với bộ lọc , không có mục nào trong số các mục con của nó sẽ hiển thị là .

Vì vậy, làm cách nào để có được QSortFilterProxyModel chỉ lọc các tệp trong thư mục chứ không phải các thư mục nằm trong thư mục đó?

Trả lời

7

Chúng tôi chạy vào một thứ tương tự ở nơi tôi làm việc và kết thúc tạo mô hình proxy của riêng chúng tôi để lọc. Tuy nhiên, nhìn qua tài liệu cho những gì bạn muốn (mà có vẻ như nó sẽ là một trường hợp phổ biến hơn), tôi đã xem qua hai khả năng.

  1. Bạn có thể đặt bộ lọc tên trên QDirModel và lọc mọi thứ theo cách đó. Tôi không có ý tưởng nếu điều này sẽ làm việc như bạn muốn, hoặc nếu các bộ lọc tên áp dụng cho các thư mục cũng có. Các tài liệu là loại thưa thớt trên các.
  2. Phân lớp QSortFilterProxyModel và ghi đè hàm filterAcceptsRow. Từ tài liệu:

Có thể thực hiện hành vi lọc tùy chỉnh bằng cách thực hiện lại bộ lọcAcceptsRow() và chức năng lọcAcceptsColumn().

Sau đó, bạn có thể sử dụng chỉ mục mô hình để kiểm tra xem mục chỉ mục là thư mục (tự động chấp nhận) hoặc tệp (lọc trên tên tệp).

1

lấy qsortfilterproxymodel và sau đó ...

bool YourQSortFilterProxyModel::filterAcceptsRow (int source_row, const QModelIndex & source_parent) const 
{ 
    if (source_parent == qobject_cast<QStandardItemModel*>(sourceModel())->invisibleRootItem()->index()) 
    { 
     // always accept children of rootitem, since we want to filter their children 
     return true; 
    } 

    return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent); 
} 
6

Đối với những người như tôi những người quan tâm đến các hành vi sau đây: nếu một đứa trẻ phù hợp với bộ lọc, sau đó tổ tiên của nó không nên được ẩn:

bool MySortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex & source_parent) const 
{ 
    // custom behaviour : 
    if(filterRegExp().isEmpty()==false) 
    { 
     // get source-model index for current row 
     QModelIndex source_index = sourceModel()->index(source_row, this->filterKeyColumn(), source_parent) ; 
     if(source_index.isValid()) 
     { 
      // if any of children matches the filter, then current index matches the filter as well 
      int i, nb = sourceModel()->rowCount(source_index) ; 
      for(i=0; i<nb; ++i) 
      { 
       if(filterAcceptsRow(i, source_index)) 
       { 
        return true ; 
       } 
      } 
      // check current index itself : 
      QString key = sourceModel()->data(source_index, filterRole()).toString(); 
      return key.contains(filterRegExp()) ; 
     } 
    } 
    // parent call for initial behaviour 
    return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent) ; 
} 
Các vấn đề liên quan