LINUX.ORG.RU

Фильтрация QTreeView с QSortFilterProxyModel

 , ,


0

0

Есть дерево вида:

Нода1

--Нода2

----Нода3 Значение1 Значение2

----Нода4 Значение3 Значение4

И так далее...

(Внешний вид дерева можно посмотреть тут)

Мне надо отфильтровать модель по различающимся значениям в одной строке. То есть, если Значение1 совпадает (равно) со Значением2, то эту строку пропускаем, если нет - выводим.

Есть пример кода:

class FindFilterProxyModel(QtCore.QSortFilterProxyModel):
    def filterAcceptsRow(self, source_row, source_parent):
        if (self.filterAcceptsRowItself(source_row, source_parent)):
            return True

        if (self.hasAcceptedChildren(source_row, source_parent)):
            return True

        return False

    def filterAcceptsRowItself(self, source_row, source_parent):
        return super(FindFilterProxyModel, self).\
        filterAcceptsRow(source_row, source_parent)

    def hasAcceptedChildren(self, source_row, source_parent):
        model = self.sourceModel()
        sourceIndex = model.index(source_row, 0, source_parent)
        if not (sourceIndex.isValid()):
            return False

        childCount = model.rowCount(sourceIndex)
        if (childCount == 0):
            return False

        for i in range (childCount): 
            if (self.filterAcceptsRowItself(i, sourceIndex)):
                return True
            if (self.hasAcceptedChildren(i, sourceIndex)):
                return True

        return False

Он рекурсивно сравнивает значения в первом столбце (использую для поиска). А мне требуется, чтобы сравнение шло по всем столбцам, кроме первого (как именно нужно переопределить filterAcceptsRow?).



Последнее исправление: max_tar (всего исправлений: 2)

Вот так на C++.

bool FindFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{
    // проверим, что моделька валидная
    if ( !sourceModel() )
        return false;

    // получим index для первого столбца проверяемой строки
    QModelIndex src_index = sourceModel()->index( source_row, 0, source_parent );

    // если нет детей, проверим значения во 2 и 3 столбцах
    if ( !sourceModel()->rowCount( src_index ) ) {
        QVariant c1 = src_index.sibling( src_index.row(), 1 ).data();
        QVariant c2 = src_index.sibling( src_index.row(), 2 ).data();

        return c1 == c2 && QSortFilterProxyModel::filterAcceptsRow( source_row, source_parent );
    }

    // рекурсивно пробежимся по дереву.
    for ( int i = 0; i < sourceModel()->rowCount( src_index ); ++i ) {
        QModelIndex child_index = src_index.child( i, 0 );
        QVariant c1 = child_index.sibling( child_index.row(), 1 ).data();
        QVariant c2 = child_index.sibling( child_index.row(), 2 ).data();

        // если есть хоть один потомок, удовлетворяющий условиям фильтра - ок!
        if ( c1 == c2 || filterAcceptsRow( i, src_index ) )
            return QSortFilterProxyModel::filterAcceptsRow( source_row, source_parent );                                                   
    }                                                                                                                                      
    QVariant c1 = src_index.sibling( src_index.row(), 1 ).data();
    QVariant c2 = src_index.sibling( src_index.row(), 2 ).data();

    return c1 == c2 && QSortFilterProxyModel::filterAcceptsRow( source_row, source_parent );                                                                                                                       
}   
grondek
()
Последнее исправление: grondek (всего исправлений: 1)
Ответ на: комментарий от grondek

Да. Можно короче:

bool FindFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{
    // проверим, что моделька валидная
    if ( !sourceModel() )
        return false;

    // получим index для первого столбца проверяемой строки
    QModelIndex src_index = sourceModel()->index( source_row, 0, source_parent );

    // рекурсивно пробежимся по дереву.
    for ( int i = 0; i < sourceModel()->rowCount( src_index ); ++i ) {
        QModelIndex child_index = src_index.child( i, 0 );
        QVariant c1 = child_index.sibling( child_index.row(), 1 ).data();
        QVariant c2 = child_index.sibling( child_index.row(), 2 ).data();

        // если есть хоть один потомок, удовлетворяющий условиям фильтра - ок!
        if ( c1 == c2 || filterAcceptsRow( i, src_index ) )
            return QSortFilterProxyModel::filterAcceptsRow( source_row, source_parent );                                                   
    }                                                                     
                                                                    // если у потомки не отфильтрованы, проверим себя
    QVariant c1 = src_index.sibling( src_index.row(), 1 ).data();
    QVariant c2 = src_index.sibling( src_index.row(), 2 ).data();

    return c1 == c2 && QSortFilterProxyModel::filterAcceptsRow( source_row, source_parent );                                                                                                                       
}   
grondek
()
Последнее исправление: grondek (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.