Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > Проблема с методом QTableView::scrollTo(...)


Автор: caustic 18.4.2008, 09:17
Доброго времени суток!
У меня реализован простейший поиск по данным в QTableView (t_cards). Модель данных - card_model. При совпадении с искомым текстом нужно, чтобы t_cards промотал ползунок до найденной строки. Указанный ниже код работает верно, кроме того, что никакой перемотки не происходит.
Код

int searchCount;
QModelIndexList searchCardList;
searchCardList = card_model->match(card_model->index(0,3),Qt::DisplayRole,(QVariant)le_search->text(),-1);
    if (searchCardList.size()!=0)
    {
        searchCount = 0;
        t_cards->setCurrentIndex(searchCardList.at(searchCount));
        t_cards->scrollTo(t_cards->currentIndex());            
    }

В описании scrollTo сказано, что это "чисто виртуальная функция" в базовом классе. Но ее реализация для QTableView уже есть. 
void QAbstractItemView::scrollTo ( const QModelIndex & index, ScrollHint hint = EnsureVisible )   [pure virtual]
Пробовал и разные ScrollHint, никакой разницы.
Что может быть не так?

   

Автор: Ken 21.4.2008, 00:47
Смотрите пример по:

http://www.crossplatform.ru/documentation/qtdoc4.3/itemviews-chart-pieview-cpp.php

В оффициальном пакете: examples/itemviews/chart/pieview.cpp

Они переопределили функцию scrollTo (). Попробуйте, надеюсь, поможет.

Автор: SABROG 21.4.2008, 08:14
Лучше разобраться почему не работает оригинальный scrollTo:

Код

void QTableView::scrollTo(const QModelIndex &index, ScrollHint hint)
{
    Q_D(QTableView);

    // check if we really need to do anything
    if (!d->isIndexValid(index)
        || (d->model->parent(index) != d->root)
        || isIndexHidden(index))
        return;

    QTableViewPrivate::Span span;
    if (d->hasSpans())
        span = d->span(index.row(), index.column());

    // Adjust horizontal position

    int viewportWidth = d->viewport->width();
    int horizontalOffset = d->horizontalHeader->offset();
    int horizontalPosition = d->horizontalHeader->sectionPosition(index.column());
    int horizontalIndex = d->horizontalHeader->visualIndex(index.column());
    int cellWidth = d->hasSpans()
                    ? d->columnSpanWidth(index.column(), span.width())
                    : d->horizontalHeader->sectionSize(index.column());

    if (horizontalScrollMode() == QAbstractItemView::ScrollPerItem) {

        bool positionAtLeft = (horizontalPosition - horizontalOffset < 0);
        bool positionAtRight = (horizontalPosition - horizontalOffset + cellWidth > viewportWidth);

        if (hint == PositionAtCenter || positionAtRight) {
            int w = (hint == PositionAtCenter ? viewportWidth / 2 : viewportWidth);
            int x = cellWidth;
            while (horizontalIndex > 0) {
                x += columnWidth(d->horizontalHeader->logicalIndex(horizontalIndex-1));
                if (x > w)
                    break;
                --horizontalIndex;
            }
        }

        if (positionAtRight || hint == PositionAtCenter || positionAtLeft) {
            int hiddenSections = 0;
            if (d->horizontalHeader->sectionsHidden()) {
                for (int s = horizontalIndex; s >= 0; --s) {
                    int column = d->horizontalHeader->logicalIndex(s);
                    if (d->horizontalHeader->isSectionHidden(column))
                        ++hiddenSections;
                }
            }
            horizontalScrollBar()->setValue(horizontalIndex - hiddenSections);
        }

    } else { // ScrollPerPixel
        if (hint == PositionAtCenter) {
            horizontalScrollBar()->setValue(horizontalPosition - ((viewportWidth - cellWidth) / 2));
        } else {
            if (horizontalPosition - horizontalOffset < 0 || cellWidth > viewportWidth)
                horizontalScrollBar()->setValue(horizontalPosition);
            else if (horizontalPosition - horizontalOffset + cellWidth > viewportWidth)
                horizontalScrollBar()->setValue(horizontalPosition - viewportWidth + cellWidth);
        }
    }

    // Adjust vertical position

    int viewportHeight = d->viewport->height();
    int verticalOffset = d->verticalHeader->offset();
    int verticalPosition = d->verticalHeader->sectionPosition(index.row());
    int verticalIndex = d->verticalHeader->visualIndex(index.row());
    int cellHeight = d->hasSpans()
                     ? d->rowSpanHeight(index.row(), span.height())
                     : d->verticalHeader->sectionSize(index.row());

    if (verticalPosition - verticalOffset < 0 || cellHeight > viewportHeight) {
        if (hint == EnsureVisible)
            hint = PositionAtTop;
    } else if (verticalPosition - verticalOffset + cellHeight > viewportHeight) {
        if (hint == EnsureVisible)
            hint = PositionAtBottom;
    }

    if (verticalScrollMode() == QAbstractItemView::ScrollPerItem) {

        if (hint == PositionAtBottom || hint == PositionAtCenter) {
            int h = (hint == PositionAtCenter ? viewportHeight / 2 : viewportHeight);
            int y = cellHeight;
            while (verticalIndex > 0) {
                int row = d->verticalHeader->logicalIndex(verticalIndex - 1);
                y += d->verticalHeader->sectionSize(row);
                if (y > h)
                    break;
                --verticalIndex;
            }
        }

        if (hint == PositionAtBottom || hint == PositionAtCenter || hint == PositionAtTop) {
            int hiddenSections = 0;
            if (d->verticalHeader->sectionsHidden()) {
                for (int s = verticalIndex; s >= 0; --s) {
                    int row = d->verticalHeader->logicalIndex(s);
                    if (d->verticalHeader->isSectionHidden(row))
                        ++hiddenSections;
                }
            }
            verticalScrollBar()->setValue(verticalIndex - hiddenSections);
        }

    } else { // ScrollPerPixel
        if (hint == PositionAtTop) {
            verticalScrollBar()->setValue(verticalPosition);
        } else if (hint == PositionAtBottom) {
            verticalScrollBar()->setValue(verticalPosition - viewportHeight + cellHeight);
        } else if (hint == PositionAtCenter) {
            verticalScrollBar()->setValue(verticalPosition - ((viewportHeight - cellHeight) / 2));
        }
    }

    d->setDirtyRegion(visualRect(index));
}

Автор: caustic 23.4.2008, 09:50
Спасибо за предложения!
Перерыл кучу исходников, пытался переопределять метод. Позже выяснил, что оригинальный scrollTo вполне нормально работает, если текущий индекс устанавливается мышкой прямо на QTableView. Долго не мог понять, в чем косяк...
В итоге, все оказалось очень просто. Довольно давно для организации сортировки в QTableView я установил QSortFilterProxyModel вместо модели card_model. А текстовый поиск осуществлялся, как и раньше, по card_model. Вот индексы и не совпадали!
Надо своевременно вносить изменения по всему коду, а то память - штука ненадежная. smile


Автор: Любитель 23.4.2008, 13:03

M
Любитель
Помечай вопрос, как решённый

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)