📄 qtreeview.cpp
字号:
d->expand(vi, true); updateGeometries(); viewport()->update(); break; case MovePageUp: return d->modelIndex(d->pageUp(vi)); case MovePageDown: return d->modelIndex(d->pageDown(vi)); case MoveHome: return model()->index(0, 0, rootIndex()); case MoveEnd: return d->modelIndex(d->viewItems.count() - 1); } return current;}/*! Applies the selection \a command to the items in or touched by the rectangle, \a rect. \sa selectionCommand()*/void QTreeView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags command){ Q_D(QTreeView); if (!selectionModel()) return; QPoint tl(isRightToLeft() ? rect.right() : rect.left(), rect.top()); QPoint br(isRightToLeft() ? rect.left() : rect.right(), rect.bottom()); QModelIndex topLeft = indexAt(tl); QModelIndex bottomRight = indexAt(br); if (selectionBehavior() != SelectRows) { QItemSelection selection; if (topLeft.isValid() && bottomRight.isValid()) { selection.append(QItemSelectionRange(topLeft, bottomRight)); selectionModel()->select(selection, command); } } else { d->select(d->viewIndex(topLeft), d->viewIndex(bottomRight), command); }}/*! Returns the rectangle from the viewport of the items in the given \a selection.*/QRegion QTreeView::visualRegionForSelection(const QItemSelection &selection) const{ if (selection.isEmpty()) return QRegion(); QRegion selectionRegion; for (int i = 0; i < selection.count(); ++i) { QItemSelectionRange range = selection.at(i); if (!range.isValid()) continue; QModelIndex parent = range.parent(); QModelIndex leftIndex = range.topLeft(); int columnCount = model()->columnCount(parent); while (leftIndex.isValid() && isIndexHidden(leftIndex)) { if (leftIndex.column() + 1 < columnCount) leftIndex = model()->index(leftIndex.row(), leftIndex.column() + 1, parent); else leftIndex = QModelIndex(); } if (!leftIndex.isValid()) continue; int top = visualRect(leftIndex).top(); QModelIndex rightIndex = range.bottomRight(); while (rightIndex.isValid() && isIndexHidden(rightIndex)) { if (rightIndex.column() - 1 >= 0) rightIndex = model()->index(rightIndex.row(), rightIndex.column() - 1, parent); else rightIndex = QModelIndex(); } if (!rightIndex.isValid()) continue; int bottom = visualRect(rightIndex).bottom(); if (top > bottom) qSwap<int>(top, bottom); int height = bottom - top + 1; for (int c = range.left(); c <= range.right(); ++c) selectionRegion += QRegion(QRect(columnViewportPosition(c), top, columnWidth(c), height)); } return selectionRegion;}/*! \reimp*/QModelIndexList QTreeView::selectedIndexes() const{ QModelIndexList viewSelected; QModelIndexList modelSelected; if (selectionModel()) modelSelected = selectionModel()->selectedIndexes(); for (int i = 0; i < modelSelected.count(); ++i) { // check that neither the parents nor the index is hidden before we add QModelIndex index = modelSelected.at(i); while (index.isValid() && !isIndexHidden(index)) index = index.parent(); if (index.isValid()) continue; viewSelected.append(modelSelected.at(i)); } return viewSelected;}/*! Scrolls the contents of the tree view by (\a dx, \a dy).*/void QTreeView::scrollContentsBy(int dx, int dy){ Q_D(QTreeView); dx = isRightToLeft() ? -dx : dx; if (dx) d->header->setOffset(horizontalScrollBar()->value()); if (d->viewItems.isEmpty()) return; // guestimate the number of items in the viewport int viewCount = d->viewport->height() / d->itemHeight; int maxDeltaY = verticalStepsPerItem() * qMin(d->viewItems.count(), viewCount); // no need to do a lot of work if we are going to redraw the whole thing anyway if (qAbs(dy) > qAbs(maxDeltaY) && d->editors.isEmpty()) { verticalScrollBar()->repaint(); d->viewport->update(); return; } if (dy) { int steps = verticalStepsPerItem(); int currentScrollbarValue = verticalScrollBar()->value(); int previousScrollbarValue = currentScrollbarValue + dy; // -(-dy) int currentViewIndex = currentScrollbarValue / steps; // the first visible item int previousViewIndex = previousScrollbarValue / steps; const QVector<QTreeViewItem> viewItems = d->viewItems; int currentY = d->topItemDelta(currentScrollbarValue, d->height(currentViewIndex)); int previousY = currentY; if ((previousViewIndex >= 0) && (previousViewIndex < d->viewItems.size())) previousY = d->topItemDelta(previousScrollbarValue, d->height(previousViewIndex)); dy = currentY - previousY; if (previousViewIndex < currentViewIndex) { // scrolling down for (int i = previousViewIndex; i < currentViewIndex; ++i) dy -= d->height(i); } else if (previousViewIndex > currentViewIndex) { // scrolling up for (int i = previousViewIndex - 1; i >= currentViewIndex; --i) dy += d->height(i); } } d->scrollContentsBy(dx, dy);}/*! This slot is called whenever a column has been moved.*/void QTreeView::columnMoved(){ QAbstractItemView::dataChanged(QModelIndex(), QModelIndex());}/*! \internal*/void QTreeView::reexpand(){ // do nothing}/*! Informs the view that the rows from the \a start row to the \a end row inclusive have been inserted into the \a parent model item.*/void QTreeView::rowsInserted(const QModelIndex &parent, int start, int end){ Q_D(QTreeView); d->doDelayedItemsLayout(); QAbstractItemView::rowsInserted(parent, start, end);}/*! Informs the view that the rows from the \a start row to the \a end row inclusive are about to removed from the given \a parent model item.*/void QTreeView::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end){ Q_D(QTreeView); if (d->viewItems.isEmpty()) return; setState(CollapsingState); if (parent == rootIndex()) { d->viewItems.clear(); d->doDelayedItemsLayout(); return; } // collapse the parent bool expanded = isExpanded(parent); d->expandParent.push(expanded); if (expanded) { int p = d->viewIndex(parent); if (p != -1) d->collapse(p, false); } QAbstractItemView::rowsAboutToBeRemoved(parent, start, end);}/*! \since 4.1 Informs the view that the rows from the \a start row to the \a end row inclusive have been removed from the given \a parent model item.*/void QTreeView::rowsRemoved(const QModelIndex &parent, int start, int end){ Q_UNUSED(start); Q_UNUSED(end); Q_D(QTreeView); if (d->viewItems.isEmpty()) return; if (parent == rootIndex()) { d->viewItems.clear(); d->doDelayedItemsLayout(); return; } bool expanded = d->expandParent.pop(); if (expanded) { int p = d->viewIndex(parent); if (p != -1) { // item is visible d->expand(p, false); d->viewport->update(); } else if (!d->expandedIndexes.contains(parent)) { d->expandedIndexes.append(parent); } } setState(NoState); d->updateScrollbars();}/*! Informs the tree view that the number of columns in the tree view has changed from \a oldCount to \a newCount.*/void QTreeView::columnCountChanged(int, int){ if (isVisible()) updateGeometries(); viewport()->update();}/*! Resizes the \a column given to the size of its contents.*/void QTreeView::resizeColumnToContents(int column){ Q_D(QTreeView); d->executePostedLayout(); if (column < 0 || column >= d->header->count()) return; int contents = sizeHintForColumn(column); int header = d->header->isHidden() ? 0 : d->header->sectionSizeHint(column); d->header->resizeSection(column, qMax(contents, header));}/*! Sorts the model by the values in the given \a column. */void QTreeView::sortByColumn(int column){ Q_D(QTreeView); if (!d->model) return; bool ascending = (header()->sortIndicatorSection() == column && header()->sortIndicatorOrder() == Qt::DescendingOrder); Qt::SortOrder order = ascending ? Qt::AscendingOrder : Qt::DescendingOrder; header()->setSortIndicator(column, order); d->model->sort(column, order);}/*! Selects all the items in the underlying model.*/void QTreeView::selectAll(){ Q_D(QTreeView); if (!selectionModel()) return; d->select(0, d->viewItems.count() - 1, QItemSelectionModel::ClearAndSelect |QItemSelectionModel::Rows);}/*! This function is called whenever \a{column}'s size is changed in the header. \a oldSize and \a newSize give the previous size and the new size in pixels.*/void QTreeView::columnResized(int column, int /* oldSize */, int /* newSize */){ Q_D(QTreeView); d->columnsToUpdate.append(column); if (d->columnResizeTimerID == 0) d->columnResizeTimerID = startTimer(0);}/*! Updates the items in the tree view. \internal*/void QTreeView::updateGeometries(){ Q_D(QTreeView); QSize hint = d->header->isHidden() ? QSize(0, 0) : d->header->sizeHint(); setViewportMargins(0, hint.height(), 0, 0); QRect vg = d->viewport->geometry(); QRect geometryRect(vg.left(), vg.top() - hint.height(), vg.width(), hint.height()); d->header->setGeometry(geometryRect); d->header->setOffset(horizontalScrollBar()->value()); if (d->header->isHidden()) QMetaObject::invokeMethod(d->header, "updateGeometries"); d->updateScrollbars(); QAbstractItemView::updateGeometries();}/*! Returns the size hint for the \a column's width or -1 if there is no model. If you need to set the width of a given column to a fixed value, call QHeaderView::resizeSection() on the view's header. If you reimplement this function in a subclass, note that the value you return is only used when resizeColumnToContents() is called. In that case, if a larger column width is required by either the view's header or the item delegate, that width will be used instead. \sa QWidget::sizeHint, header()*/int QTreeView::sizeHintForColumn(int column) const{ Q_D(const QTreeView); if (d->viewItems.isEmpty()) return -1; int w = 0; QStyleOptionViewItem option = viewOptions(); QAbstractItemDelegate *delegate = itemDelegate(); const QVector<QTreeViewItem> viewItems = d->viewItems; for (int i = 0; i < viewItems.count(); ++i) { QModelIndex index = viewItems.at(i).index; if (index.column() != column) index = index.sibling(index.row(), column); int width = delegate->sizeHint(option, index).width(); w = qMax(w, width + (column == 0 ? d->indentation(i) : 0)); } return w;}/*! Returns the size hint for the row indicated by \a index. \sa sizeHintForColumn(), uniformRowHeights()*/int QTreeView::indexRowSizeHint(const QModelIndex &index) const{ Q_D(const QTreeView); if (!index.isValid() || !model()) return -1; int start = -1; int end = -1; int count = d->header->count(); if (count) { // If the sections have moved, we end up checking too many or too few start = d->header->logicalIndexAt(0); end = d->header->logicalIndexAt(viewport()->width()); } else { // If the header has not been layed out yet, we use the model directly count = model()->columnCount(index.parent()); } if (isRightToLeft()) { start = (start == -1 ? count - 1 : start); end = (end == -1 ? 0 : end); } else { start = (start == -1 ? 0 : start); end = (end == -1 ? count - 1 : end); } int tmp = start; start = qMin(start, end); end = qMax(tmp, end); int height = -1; QStyleOptionViewItem option = viewOptions(); // This is temporary hack to speed up the function and will go away in 4.2 option.rect.setWidth(-1); QAbstractItemDelegate *delegate = itemDelegate(); for (int column = start; column <= end; ++column) { QModelIndex idx = index.sibling(index.row(), column); if (idx.isValid()) { if (QWidget *editor = d->editorForIndex(idx)) height = qMax(height, editor->size().height()); height = qMax(height, delegate->sizeHint(option, idx).height());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -