Trolltech Home | Qt-interest Home | Recent Threads | All Threads | Author | Date
All threads index page 3

Qt-interest Archive, January 2008
Assert in QSortFilterProxyModel


Message 1 in thread

Hi Everyone,
I use QT 4.2.3 as my GUI application toolkit on Linux platform.

I have a QTabWidget with 3 tabs inside. Each tab is a QTreeView.
I also have a QStandardItemModel as 1st QTreeView model. Then
the 2nd and 3rd QTreeView is using QSortFilterProxyModel from
1st QStandardItemModel.

But I found I got assertion in QT when I try to removeRow from 1st
QStandardItemModel.
The removed items will only appear in 2nd QSortFilterProxyModel.
They will be filtered by 3rd QSortFilterProxyModel.

Also, I have change selection before the remove action.

It asserts inside :

/*!
  \internal
  updates the mapping of the children when inserting or removing items
*/
void QSortFilterProxyModelPrivate::updateChildrenMapping(const QModelIndex
&source_parent, Mapping *parent_mapping,
                                                         Qt::Orientation
orient, int start, int end, int delta_item_count, bool remove)
{
    // see if any mapped children should be (re)moved
    QVector<QModelIndex>::iterator it2 =
parent_mapping->mapped_children.begin();
    for ( ; it2 != parent_mapping->mapped_children.end();) {
        const QModelIndex source_child_index = *it2;
        const int pos = (orient == Qt::Vertical)
                        ? source_child_index.row()
                        : source_child_index.column();
        if (pos < start) {
            // not affected
            ++it2;
        } else if (remove && pos <= end) {
            // in the removed interval
            it2 = parent_mapping->mapped_children.erase(it2);
            remove_from_mapping(source_child_index);
        } else {
            // below the removed items -- recompute the index
            QModelIndex new_index;
            const int newpos = remove ? pos - delta_item_count : pos +
delta_item_count;
            if (orient == Qt::Vertical) {
                new_index = model->index(newpos,
                                         source_child_index.column(),
                                         source_parent);
            } else {
                new_index = model->index(source_child_index.row(),
                                         newpos,
                                         source_parent);
            }
            *it2 = new_index;
            ++it2;

            // update mapping
            Mapping *cm = source_index_mapping.take(source_child_index);
            Q_ASSERT(cm);
<=========================== it asserts here !!
            cm->map_iter = source_index_mapping.insert(new_index, cm);
        }
    }
}


Could anybody help me out ?

Regards,
Pagan


--
 [ signature omitted ] 

Message 2 in thread

Hi Everyone,
I found more detailed information after I step inside QT source code
to debug.

void QSortFilterProxyModelPrivate::updateChildrenMapping(const QModelIndex &source_parent, Mapping *parent_mapping,
                                                         Qt::Orientation orient, int start, int end, int delta_item_count, bool remove)

Inside this API, it will traverse 
    QVector<QModelIndex>::iterator it2 = parent_mapping->mapped_children.begin();
    for ( ; it2 != parent_mapping->mapped_children.end();) {
        const QModelIndex source_child_index = *it2;


If I turn off the sorting of this model corresponding view, I found the source_child_index
start from 0 to the end when I removeRow from source model.

If I turn on the sorting, I found the source_child_index start from an arbitrary row.

But in this API more further below :

            // update mapping
            Mapping *cm = source_index_mapping.take(source_child_index);
            Q_ASSERT(cm);
            cm->map_iter = source_index_mapping.insert(new_index, cm);

It needs assumption for the traverse start from 0. Otherwise, it will erase all index.

Is it a QT internal bug ?

I've checked all related tasks in QT Task Tracker but found none matches.

Regards,
Pagan


"Pagan Chou" <pagan_chou@xxxxxxxxxxxxxx> 在郵件 news:fncgi8$pf3$1@xxxxxxxxxxxxxxxxxx 中撰寫...
> Hi Everyone,
> I use QT 4.2.3 as my GUI application toolkit on Linux platform.
> 
> I have a QTabWidget with 3 tabs inside. Each tab is a QTreeView.
> I also have a QStandardItemModel as 1st QTreeView model. Then
> the 2nd and 3rd QTreeView is using QSortFilterProxyModel from
> 1st QStandardItemModel.
> 
> But I found I got assertion in QT when I try to removeRow from 1st
> QStandardItemModel.
> The removed items will only appear in 2nd QSortFilterProxyModel.
> They will be filtered by 3rd QSortFilterProxyModel.
> 
> Also, I have change selection before the remove action.
>