2013-07-08 4 views
4

Qt 4.8QTreeView :: scrollTo не работает

У меня есть класс с QTreeView на основе с asociated класса на основе QAbstractItemModel. Если я перезагружу модель новой информацией, я хочу развернуть/прокрутить дерево до предыдущего выбранного элемента.

Оба класа, древовидная структура и модель правильно созданы и подключены с использованием QTreeView::setSelectionModel(...), работая правильно.

После перезагрузки модели, я получаю правильный индекс к предыдущему выбранному элементу, и я scrollTo его:

myTreeView->scrollTo(index); 

но дерево не расширяется. Однако, если я разворачиваю дерево вручную, элемент действительно выбран.

вид дерева инициализируется в contruct с:

header()->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel); 
header()->setStretchLastSection(false); 
header()->setResizeMode(0, QHeaderView::ResizeToContents); 

Любая идея о расширении дерева на выбор?

+0

Его ошибка и не исправлена ​​в Qt 4.x, https://bugreports.qt.io/browse/QTBUG-9326 – NDestiny

ответ

0

QTreeView::scrollTo следует соответствующим образом развернуть иерархию.

Возможно, ваш объект QModelIndex недействителен при обновлении модели (и, возможно, по-прежнему выбирает правильную строку, потому что информация о строке по-прежнему действительна, хотя исходное изображение отсутствует, не спрашивайте меня, как работают эти внутренние элементы). Из QModelIndexdocumentation:

Примечание: Модельные индексы следует использовать сразу, а затем выбросить. Вы не должны полагаться на индексы, чтобы оставаться в силе после вызова функций модели, которые изменяют структуру модели или удаляют элементы. Если вам нужно поддерживать индекс модели с течением времени, используйте QPersistentModelIndex.

Вы, конечно, можете заглянуть в QPersistentModelIndex объект, но, как он говорит в своем documentation:

Это хорошая практика, чтобы проверить, что постоянные модельные индексы действительны до их использования.

В противном случае вы всегда можете запросить этот элемент снова после обновления модели.

+0

бы хорошо, если бы это решило проблему, но я создаю модель индекс в существующей модели, основанный на чистых целочисленных данных «первый ребенок второго ребенка четвертого ребенка ...», и он все равно не работал. – IceFire

1

Даже QTreeView::scrollTo документация говорит:

Scroll the contents of the tree view until the given model item index is 
visible. The hint parameter specifies more precisely where the item should 
be located after the operation. If any of the parents of the model item 
are collapsed, they will be expanded to ensure that the model item is visible. 

Это не совсем верно (я думаю)

Если решить проблему расширяющегося все предыдущие уровни дерева вручную:

// This slot is invoqued from model using last selected item 
void MyTreeWidget::ItemSelectedManually(const QModelIndex & ar_index) 
{ 
    std::vector<std::pair<int, int> > indexes; 

    // first of all, I save all item "offsets" relative to its parent 

    QModelIndex indexAbobe = ar_index.parent(); 
    while (indexAbobe.isValid()) 
    { 
     indexes.push_back(std::make_pair(indexAbobe.row(), indexAbobe.column())); 
     indexAbobe = indexAbobe.parent(); 
    } 

    // now, select actual selection model 

    auto model = _viewer.selectionModel()->model(); 

    // get root item 

    QModelIndex index = model->index(0, 0, QModelIndex()); 
    if (index.isValid()) 
    { 
     // now, expand all items below 

     for (auto it = indexes.rbegin(); it != indexes.rend() && index.isValid(); ++it) 
     { 
      auto row = (*it).first; 
      auto colum = (*it).second; 

      _viewer.setExpanded(index, true); 

      // and get a new item relative to parent 
      index = model->index(row, colum, index); 
     } 
    } 

    // finally, scroll to real item, after expanding everything above. 
    _viewer.scrollTo(ar_index); 
} 
2

Я просто дело с аналогичной ситуацией установка индекса модели через setModelIndex (который внутри заканчивается с scrollTo) работал нормально для одной из моих моделей, но плохо для другой o северо-восток

Когда я решительно развернул все предметы уровня 1, scrollTo работал так же, как описано выше (достаточно указать expandAll).

Причина была ошибка в моем классе модели в:

QModelIndex MyBadModel::parent(const QModelIndex& index) const 

и, как я установил, что все стало нормально там. Ошибка была такой, что internalId индекса родительской модели не был таким же, как при вычислении этого же индекса модели (для родителя) «из другого направления», поэтому в этом модельном индексе (возвращаемом методом parent) не удалось найти в списке визуальных показателей.

+0

@ tio-pepe должен принять это как ответ, потому что одна и та же проблема возникает со мной. Ошибка в реализации * parent * вызывает отказ QTreeView :: scrollTo. – McLeary

0

Все было просто. Просто измените свойство autoExpandDelay от -1 до 0 (например).

ui->treeView->setAutoExpandDelay(0); 
Смежные вопросы