分享個作項目遇到的:QSortFilterProxyModel實現QTreeView的過濾的缺...

    通常若是須要對一個視圖進行關鍵字過濾,咱們會使用QT的類QSortFilterProxyModel,將視圖(view)的模型設置爲這個代理類,將代理類的源模型定義爲原始模型,而後定義代理模型的filterKeyColumn, filterRole, filterFixString或filterRegExp等屬性後就能夠實現過濾功能。如:函數

MyTreeModel model;  
QSortFilterProxyModel sfmodel;  
MyView view;  
  
view.setModel(&sfmodel);  
sfmodel.setSourceModel(&model);  
sfmodel.setFilterKeyColumn(0);  // optional  
sfmodel.setFilterRole(Qt::DisplayRole); // default, optional  
sfmodel.setFilterFixedString("keyword");  
sfmodel.setFilterRegExp("[hH]ello");

    可是對於TreeView和TreeModel,這樣的作法有些缺陷,若是在子節點上的數據根據過濾規則能夠顯示,但它的parent節點根據過濾規則是不顯示的。這樣一來會由於父節點被過濾掉,而致使符合條件的子節點也一塊兒被過濾掉了。若是須要對這個缺陷進行改進,能夠這樣來作:QSortFilterProxyModel繼承一個本身的代理類,從新實現它的filterAcceptsRow函數,當節點不是一個葉子節點(在末端,沒有子節點)時不該用過濾規則,只對葉子節點應用過濾規則,這樣就能夠達到上述要求。代碼以下:
spa

bool MyFilterProxyModel::filterAcceptsRow ( int source_row,  
                            const QModelIndex & source_parent ) const  
{  
    QModelIndex source_index = sourceModel()->index(source_row, 0, source_parent);  
    if (sourceModel()->rowCount(source_index)>0)  
        return true;  
    else  
        return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);  
}

    上面的代碼會帶來一個新的缺陷,就是對於非葉子節點不該用過濾規則,對於那些沒有子節點符合過濾規則,且自身節點也不符合過濾規則的節點,也會一直在視圖中顯示。若是須要彌補這個問題,能夠繼續作如下的改進:在應用過濾規則時,若是自身不符合過濾規則,再去檢查全部的子節點(遞歸調用至全部的後代節點),若全部的子節點都不符合過濾規則,那麼這個子節點就不顯示,只要有一個後代節點符合規則,就須要顯示這個節點。代碼以下:代理

bool MyFilterProxyModel::filterAcceptsRow ( int source_row,  
                            const QModelIndex & source_parent ) const  
{  
    bool filter = QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);  
  
    if (filter)  
    {  
        return true;  
    }  
    else  
    {  
        // check all decendant's  
        QModelIndex source_index = sourceModel()->index(source_row, 0, source_parent);  
        for (int k=0; k<sourceModel()->rowCount(source_index); k++)  
        {  
            if (filterAcceptsRow(k, source_index))  
            {  
                return true;  
            }  
        }  
    }  
  
    return false;  
}

按照這樣的作法,就能夠達到一個比較理想的過濾效果。code

相關文章
相關標籤/搜索