📄 qheaderview.cpp
字号:
} } sectionHidden = newSectionHidden; } if (visualIndices.isEmpty() && logicalIndices.isEmpty()) { for (int i = logicalFirst; i <= changeCount+logicalFirst; ++i) hiddenSectionSize.remove(i); //Q_ASSERT(headerSectionCount() == sectionCount); removeSectionsFromSpans(logicalFirst, logicalLast); } else { for (int l = logicalLast; l >= logicalFirst; --l) { int visual = visualIndices.at(l); for (int v = 0; v < sectionCount; ++v) { if (v >= logicalIndices.count()) continue; // the section doesn't exist if (v > visual) { int logical = logicalIndices.at(v); --(visualIndices[logical]); } if (logicalIndex(v) > l) // no need to move the positions before l --(logicalIndices[v]); } hiddenSectionSize.remove(l); logicalIndices.remove(visual); visualIndices.remove(l); //Q_ASSERT(headerSectionCount() == sectionCount); removeSectionsFromSpans(visual, visual); } // ### handle sectionSelection, sectionHidden } sectionCount -= changeCount; // if we only have the last section (the "end" position) left, the header is empty if (sectionCount <= 0) clear(); invalidateCachedSizeHint(); emit q->sectionCountChanged(oldCount, q->count()); viewport->update();}void QHeaderViewPrivate::_q_layoutAboutToBeChanged(){ for (int i = 0; i < sectionHidden.count(); ++i) if (sectionHidden.testBit(i)) // ### note that we are using column or row 0 persistentHiddenSections.append(orientation == Qt::Horizontal ? model->index(0, logicalIndex(i), root) : model->index(logicalIndex(i), 0, root));}void QHeaderViewPrivate::_q_layoutChanged(){ Q_Q(QHeaderView); if (persistentHiddenSections.isEmpty()) { if (modelSectionCount() != sectionCount) q->initializeSections(); return; } bool sectionCountChanged = false; for (int i = 0; i < persistentHiddenSections.count(); ++i) { QModelIndex index = persistentHiddenSections.at(i); if (index.isValid()) { const int logical = (orientation == Qt::Horizontal ? index.column() : index.row()); sectionHidden.setBit(visualIndex(logical)); } else if (!sectionCountChanged && (modelSectionCount() != sectionCount)) { sectionCountChanged = true; break; } // if the index was invalidated, but the section count is unchanged, // let the section be in the same hidden state as before } persistentHiddenSections.clear(); // the number of sections changed; we need to reread the state of the model if (sectionCountChanged) q->initializeSections();}/*! \internal*/void QHeaderView::initializeSections(){ Q_D(QHeaderView); const int oldCount = d->sectionCount; const int newCount = d->modelSectionCount(); if (newCount <= 0) { d->clear(); emit sectionCountChanged(oldCount, 0); } else if (newCount != oldCount) { const int min = qBound(0, oldCount, newCount - 1); initializeSections(min, newCount - 1); if (stretchLastSection()) // we've already gotten the size hint d->lastSectionSize = sectionSize(logicalIndex(d->sectionCount - 1)); } else if (d->forceInitializing) { initializeSections(0, newCount - 1); d->forceInitializing = false; }}/*! \internal*/void QHeaderView::initializeSections(int start, int end){ Q_D(QHeaderView); Q_ASSERT(start >= 0); Q_ASSERT(end >= 0); d->executePostedLayout(); d->invalidateCachedSizeHint(); if (end < d->sectionCount) { int newCount = end + 1; d->removeSectionsFromSpans(newCount, d->sectionCount); if (!d->hiddenSectionSize.isEmpty()) { if (d->sectionCount - newCount > d->hiddenSectionSize.count()) { for (int i = end + 1; i < d->sectionCount; ++i) d->hiddenSectionSize.remove(i); } else { QHash<int, int>::iterator it = d->hiddenSectionSize.begin(); while (it != d->hiddenSectionSize.constEnd()) { if (it.key() >= start && it.key() <= end) it = d->hiddenSectionSize.erase(it); else ++it; } } } } int oldCount = d->sectionCount; d->sectionCount = end + 1; if (!d->logicalIndices.isEmpty()) { d->logicalIndices.resize(d->sectionCount); d->visualIndices.resize(d->sectionCount); for (int i = start; i < d->sectionCount; ++i){ d->logicalIndices[i] = i; d->visualIndices[i] = i; } } if (d->globalResizeMode == Stretch) d->stretchSections = d->sectionCount; else if (d->globalResizeMode == ResizeToContents) d->contentsSections = d->sectionCount; if (!d->sectionHidden.isEmpty()) d->sectionHidden.resize(d->sectionCount); if (d->sectionCount > oldCount || d->forceInitializing) d->createSectionSpan(start, end, (end - start + 1) * d->defaultSectionSize, d->globalResizeMode); //Q_ASSERT(d->headerLength() == d->length); if (d->sectionCount != oldCount) emit sectionCountChanged(oldCount, d->sectionCount); d->viewport->update();}/*! \reimp*/void QHeaderView::currentChanged(const QModelIndex ¤t, const QModelIndex &old){ Q_D(QHeaderView); if (d->orientation == Qt::Horizontal && current.column() != old.column()) { if (old.isValid() && old.parent() == d->root) d->setDirtyRegion(QRect(sectionViewportPosition(old.column()), 0, sectionSize(old.column()), d->viewport->height())); if (current.isValid() && current.parent() == d->root) d->setDirtyRegion(QRect(sectionViewportPosition(current.column()), 0, sectionSize(current.column()), d->viewport->height())); } else if (d->orientation == Qt::Vertical && current.row() != old.row()) { if (old.isValid() && old.parent() == d->root) d->setDirtyRegion(QRect(0, sectionViewportPosition(old.row()), d->viewport->width(), sectionSize(old.row()))); if (current.isValid() && current.parent() == d->root) d->setDirtyRegion(QRect(0, sectionViewportPosition(current.row()), d->viewport->width(), sectionSize(current.row()))); } d->updateDirtyRegion();}/*! \reimp*/bool QHeaderView::event(QEvent *e){ Q_D(QHeaderView); switch (e->type()) { case QEvent::HoverEnter: { QHoverEvent *he = static_cast<QHoverEvent*>(e); d->hover = logicalIndexAt(he->pos()); if (d->hover != -1) updateSection(d->hover); break; } case QEvent::HoverLeave: { if (d->hover != -1) updateSection(d->hover); d->hover = -1; break; } case QEvent::HoverMove: { QHoverEvent *he = static_cast<QHoverEvent*>(e); int oldHover = d->hover; d->hover = logicalIndexAt(he->pos()); if (d->hover != oldHover) { if (oldHover != -1) updateSection(oldHover); if (d->hover != -1) updateSection(d->hover); } break; } default: break; } return QAbstractItemView::event(e);}/*! \reimp*/void QHeaderView::paintEvent(QPaintEvent *e){ Q_D(QHeaderView); if (count() == 0) return; QPainter painter(d->viewport); const QPoint offset = d->scrollDelayOffset; QRect translatedEventRect = e->rect(); translatedEventRect.translate(offset); int start = -1; int end = -1; if (d->orientation == Qt::Horizontal) { start = visualIndexAt(translatedEventRect.left()); end = visualIndexAt(translatedEventRect.right()); } else { start = visualIndexAt(translatedEventRect.top()); end = visualIndexAt(translatedEventRect.bottom()); } if (d->reverse()) { 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); d->prepareSectionSelected(); // clear and resize the bit array QRect currentSectionRect; int logical; const int width = d->viewport->width(); const int height = d->viewport->height(); for (int i = start; i <= end; ++i) { if (d->isVisualIndexHidden(i)) continue; painter.save(); logical = logicalIndex(i); if (d->orientation == Qt::Horizontal) { currentSectionRect.setRect(sectionViewportPosition(logical), 0, sectionSize(logical), height); } else { currentSectionRect.setRect(0, sectionViewportPosition(logical), width, sectionSize(logical)); } currentSectionRect.translate(offset); QVariant variant = d->model->headerData(logical, d->orientation, Qt::FontRole); if (variant.isValid() && qVariantCanConvert<QFont>(variant)) { QFont sectionFont = qvariant_cast<QFont>(variant); painter.setFont(sectionFont); } paintSection(&painter, currentSectionRect, logical); painter.restore(); } QStyleOption opt; opt.init(this); // Paint the area beyond where there are indexes if (d->reverse()) { opt.state |= QStyle::State_Horizontal; if (currentSectionRect.left() > translatedEventRect.left()) { opt.rect = QRect(translatedEventRect.left(), 0, currentSectionRect.left() - translatedEventRect.left(), height); style()->drawControl(QStyle::CE_HeaderEmptyArea, &opt, &painter, this); } } else if (currentSectionRect.right() < translatedEventRect.right()) { // paint to the right opt.state |= QStyle::State_Horizontal; opt.rect = QRect(currentSectionRect.right() + 1, 0, translatedEventRect.right() - currentSectionRect.right(), height); style()->drawControl(QStyle::CE_HeaderEmptyArea, &opt, &painter, this); } else if (currentSectionRect.bottom() < translatedEventRect.bottom()) { // paint the bottom section opt.state &= ~QStyle::State_Horizontal; opt.rect = QRect(0, currentSectionRect.bottom() + 1, width, height - currentSectionRect.bottom() - 1); style()->drawControl(QStyle::CE_HeaderEmptyArea, &opt, &painter, this); }#if 0 // ### visualize section spans for (int a = 0, i = 0; i < d->sectionSpans.count(); ++i) { QColor color((i & 4 ? 255 : 0), (i & 2 ? 255 : 0), (i & 1 ? 255 : 0)); if (d->orientation == Qt::Horizontal) painter.fillRect(a - d->offset, 0, d->sectionSpans.at(i).size, 4, color); else painter.fillRect(0, a - d->offset, 4, d->sectionSpans.at(i).size, color); a += d->sectionSpans.at(i).size; }#endif}/*! \reimp*/void QHeaderView::mousePressEvent(QMouseEvent *e){ Q_D(QHeaderView); if (d->state != QHeaderViewPrivate::NoState || e->button() != Qt::LeftButton) return; int pos = d->orientation == Qt::Horizontal ? e->x() : e->y(); int handle = d->sectionHandleAt(pos); d->originalSize = -1; // clear the stored original size while (handle > -1 && isSectionHidden(handle)) --handle; if (handle == -1) { d->pressed = logicalIndexAt(pos); if (d->clickableSections) emit sectionPressed(d->pressed); if (d->movableSections) { d->section = d->target = d->pressed; if (d->section == -1) return; d->state = QHeaderViewPrivate::MoveSection; d->setupSectionIndicator(d->section, pos); } else if (d->clickableSections && d->pressed != -1) { updateSection(d->pressed); d->state = QHeaderViewPrivate::SelectSections; } } else if (resizeMode(handle) == Interactive) { d->originalSize = sectionSize(handle); d->state = QHeaderViewPrivate::ResizeSection; d->section = handle; } d->firstPos = pos; d->lastPos = pos; d->clearCascadingSections();}/*! \reimp*/void QHeaderView::mouseMoveEvent(QMouseEvent *e){ Q_D(QHeaderView); int pos = d->orientation == Qt::Horizontal ? e->x() : e->y(); if (pos < 0) return; if (e->buttons() == Qt::NoButton) { d->state = QHeaderViewPrivate::NoState; d->pressed = -1; } switch (d->state) { case QHeaderViewPrivate::ResizeSection: { Q_ASSERT(d->originalSize != -1); if (d->cascadingResizing) { int delta = d->reverse() ? d->lastPos - pos : pos - d->lastPos; int visual = visualIndex(d->section); d->cascadingResize(visual, d->headerSectionSize(visual) + delta); } else { int delta = d->reverse() ? d->firstPos - pos : pos - d->firstPos; resizeSection(d->section, qMax(d->originalSize + delta, minimumSectionSize())); } d->lastPos = pos; return; } case QHeaderViewPrivate::MoveSection: { if (qAbs(pos - d->firstPos) >= QApplication::startDragDistance()) { int indicatorCenter = (d->orientation == Qt::Horizontal ? d->sectionIndicator->width() : d->sectionIndicator->height()) / 2; int centerOffset = indicatorCenter - d->sectionIndicatorOffset; // This will drop the moved section to the position under the center of the indicator. // If centerOffset is 0, the section will be moved to the position of the mouse cursor. int visual = visualIndexAt(pos + centerOffset); if (visual == -1) return; d->target = d->logicalIndex(visual); d->updateSectionIndicator(d->section, pos); } else { int visual = visualIndexAt(d->firstPos); if (visual == -1) return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -