📄 qheaderview.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2006 Trolltech ASA. All rights reserved.**** This file is part of the QtGui module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://www.trolltech.com/products/qt/opensource.html**** If you are unsure which license is appropriate for your use, please** review the following information:** http://www.trolltech.com/products/qt/licensing.html or contact the** sales department at sales@trolltech.com.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "qheaderview.h"#ifndef QT_NO_ITEMVIEWS#include <qbitarray.h>#include <qdebug.h>#include <qevent.h>#include <qpainter.h>#include <qscrollbar.h>#include <qtooltip.h>#include <qwhatsthis.h>#include <qstyle.h>#include <qstyleoption.h>#include <qvector.h>#include <qapplication.h>#include <qvarlengtharray.h>#include <qabstractitemdelegate.h>#include <qvariant.h>#include <private/qheaderview_p.h>/*! \class QHeaderView \brief The QHeaderView class provides a header row or header column for item views. \ingroup model-view \mainclass A QHeaderView displays the headers used in item views such as the QTableView and QTreeView classes. It takes the place of the \c QHeader class previously used for the same purpose, but uses the Qt's model/view architecture for consistency with the item view classes. The QHeaderView class is one of the \l{Model/View Classes} and is part of Qt's \l{Model/View Programming}{model/view framework}. The model gets the data for each section from the model using the getHeaderData() function. You can set the data by using setHeaderData(). Each header has an orientation() and a number of sections, given by the count() function. Sections can be moved and resized using moveSection() and resizeSection(); they can be hidden and shown with hideSection() and showSection(). Each section of a header is described by a section ID, specified by its section(), and can be located at a particular visualIndex() in the header. A section can have a sort indicator set with setSortIndicator(); this indicates whether the items in the associated item view will be sorted in the order given by the section. A header can be fixed in place, or made movable with setMovable(). It can be made clickable with setClickable(), and has resizing behavior in accordance with setResizeMode(). A header emits sectionMoved() if the user moves a section, sectionResized() if the user resizes a section, and sectionClicked() and sectionHandleDoubleClicked() in response to mouse clicks. A header also emits sectionCountChanged() and sectionAutoResize(). You can identify a section using the logicalIndex() and logicalIndexAt() functions, or by its index position, using the visualIndex() and visualIndexAt() functions. The visual index will change if a section is moved while the logical index wont change. For a horizontal header the section is equivalent to a column in the model, and for a vertical header the section is equivalent to a row in the model. \sa {Model/View Programming}, QListView, QTableView, QTreeView*//*! \enum QHeaderView::ResizeMode \value Interactive Don't automatically change the size (let the user do it manually). \value Stretch Fill all the available visible space. \value Custom Don't automatically change the size here, leave it to some other object.*//*! \fn void QHeaderView::sectionMoved(int logicalIndex, int oldVisualIndex, int newVisualIndex) This signal is emitted when a section is moved. The section's logical index is specified by \a logicalIndex, the old index by \a oldVisualIndex, and the new index position by \a newVisualIndex. \sa moveSection()*//*! \fn void QHeaderView::sectionResized(int logicalIndex, int oldSize, int newSize) This signal is emitted when a section is resized. The section's logical number is specified by \a logicalIndex, the old size by \a oldSize, and the new size by \a newSize. \sa resizeSection*//*! \fn void QHeaderView::sectionPressed(int logicalIndex) This signal is emitted when a section is pressed. The section's logical index is specified by \a logicalIndex. \sa setClickable()*//*! \fn void QHeaderView::sectionClicked(int logicalIndex) This signal is emitted when a section is clicked. The section's logical index is specified by \a logicalIndex. Note that you will also get a sectionPressed \sa setClickable()*//*! \fn void QHeaderView::sectionDoubleClicked(int logicalIndex) This signal is emitted when a section is double-clicked. The section's logical index is specified by \a logicalIndex. \sa setClickable()*//*! \fn void QHeaderView::sectionCountChanged(int oldCount, int newCount) This signal is emitted when the number of sections changes; i.e. when sections are added or deleted. The original count is specified by \a oldCount, and the new count by \a newCount. \sa count(), length(), headerDataChanged()*//*! \fn void QHeaderView::sectionHandleDoubleClicked(int logicalIndex) This signal is emitted when a section is double-clicked. The section's logical index is specified by \a logicalIndex. \sa setClickable()*//*! \fn void QHeaderView::sectionAutoResize(int logicalIndex, QHeaderView::ResizeMode mode) This signal is emitted when a section is automatically resized. The section's logical index is specified by \a logicalIndex, and the resize mode by \a mode. \sa setResizeMode(), stretchLastSection()*//*! \property QHeaderView::highlightSections \brief whether the sections containing selected items are highlighted*//*! Creates a new generic header with the given \a orientation and \a parent.*/QHeaderView::QHeaderView(Qt::Orientation orientation, QWidget *parent) : QAbstractItemView(*new QHeaderViewPrivate, parent){ Q_D(QHeaderView); d->orientation = orientation; d->defaultSectionSize = (orientation == Qt::Horizontal ? 100 : 30); d->defaultAlignment = (orientation == Qt::Horizontal ? Qt::Alignment(Qt::AlignCenter) : Qt::AlignLeft|Qt::AlignVCenter); initialize();}/*! \internal*/QHeaderView::QHeaderView(QHeaderViewPrivate &dd, Qt::Orientation orientation, QWidget *parent) : QAbstractItemView(dd, parent){ Q_D(QHeaderView); d->orientation = orientation; d->defaultSectionSize = (orientation == Qt::Horizontal ? 100 : 30); d->defaultAlignment = (orientation == Qt::Horizontal ? Qt::Alignment(Qt::AlignCenter) : Qt::AlignLeft|Qt::AlignVCenter); initialize();}/*! Destroys the header.*/QHeaderView::~QHeaderView(){}/*! \internal*/void QHeaderView::initialize(){ Q_D(QHeaderView); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setFrameStyle(NoFrame); d->viewport->setMouseTracking(true); d->viewport->setBackgroundRole(QPalette::Button); delete d->delegate;}/*! \reimp*/void QHeaderView::setModel(QAbstractItemModel *model){ Q_D(QHeaderView); if (d->model) { if (d->orientation == Qt::Horizontal) { QObject::disconnect(d->model, SIGNAL(columnsInserted(QModelIndex,int,int)), this, SLOT(sectionsInserted(QModelIndex,int,int))); QObject::disconnect(d->model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)), this, SLOT(sectionsAboutToBeRemoved(QModelIndex,int,int))); QObject::disconnect(d->model, SIGNAL(columnsRemoved(QModelIndex,int,int)), this, SLOT(_q_sectionsRemoved(QModelIndex,int,int))); } else { QObject::disconnect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(sectionsInserted(QModelIndex,int,int))); QObject::disconnect(d->model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), this, SLOT(sectionsAboutToBeRemoved(QModelIndex,int,int))); QObject::disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(_q_sectionsRemoved(QModelIndex,int,int))); } QObject::disconnect(d->model, SIGNAL(headerDataChanged(Qt::Orientation,int,int)), this, SLOT(headerDataChanged(Qt::Orientation,int,int))); } if (model) { if (d->orientation == Qt::Horizontal) { QObject::connect(model, SIGNAL(columnsInserted(QModelIndex,int,int)), this, SLOT(sectionsInserted(QModelIndex,int,int))); QObject::connect(model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)), this, SLOT(sectionsAboutToBeRemoved(QModelIndex,int,int))); QObject::connect(model, SIGNAL(columnsRemoved(QModelIndex,int,int)), this, SLOT(_q_sectionsRemoved(QModelIndex,int,int))); } else { QObject::connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(sectionsInserted(QModelIndex,int,int))); QObject::connect(model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), this, SLOT(sectionsAboutToBeRemoved(QModelIndex,int,int))); QObject::connect(model, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(_q_sectionsRemoved(QModelIndex,int,int))); } QObject::connect(model, SIGNAL(headerDataChanged(Qt::Orientation,int,int)), this, SLOT(headerDataChanged(Qt::Orientation,int,int))); } d->clear(); QAbstractItemView::setModel(model); // Users want to set sizes and modes before the widget is shown. // Thus, we have to initialize when the model is set, // and not lazily like we do in the other views. initializeSections();}/*! Returns the orientation of the header. \sa Qt::Orientation*/Qt::Orientation QHeaderView::orientation() const{ Q_D(const QHeaderView); return d->orientation;}/*! Returns the offset of the header: this is the header's left-most (or top-most for vertical headers) visible pixel. \sa setOffset()*/int QHeaderView::offset() const{ Q_D(const QHeaderView); return d->offset;}/*! \fn void QHeaderView::setOffset(int offset) Sets the header's offset to \a offset. \sa offset(), length()*/void QHeaderView::setOffset(int newOffset){ Q_D(QHeaderView); if (d->offset == newOffset) return; int ndelta = d->offset - newOffset; d->offset = newOffset; if (d->orientation == Qt::Horizontal) d->viewport->scroll(isRightToLeft() ? -ndelta : ndelta, 0); else d->viewport->scroll(0, ndelta);}/*! Returns the length along the orientation of the header. \sa sizeHint(), setResizeMode(), offset()*/int QHeaderView::length() const{ Q_D(const QHeaderView); if (d->sections.count()) return d->sections.last().position; return 0;}/*! Returns a suitable size hint for this header. \sa sectionSizeHint()*/QSize QHeaderView::sizeHint() const{ Q_D(const QHeaderView); if (d->model == 0 || count() < 1) return QSize(0, 0); if (d->cachedSizeHint.isValid()) return d->cachedSizeHint; int width = 0; int height = 0; // get size hint for the first n sections int c = qMin(count(), 100); for (int i = 0; i < c; ++i) { QSize hint = sectionSizeFromContents(i); width = qMax(hint.width(), width); height = qMax(hint.height(), height); } // get size hint for the last n sections c = qMax(count() - 100, c); for (int j = count() - 1; j >= c; --j) { QSize hint = sectionSizeFromContents(j); width = qMax(hint.width(), width); height = qMax(hint.height(), height); } d->cachedSizeHint = QSize(width, height); return d->cachedSizeHint;}/*! Returns a suitable size hint for the section specified by \a logicalIndex. \sa sizeHint(), defaultSectionSize()*/int QHeaderView::sectionSizeHint(int logicalIndex) const{ Q_D(const QHeaderView); if (d->model == 0 || logicalIndex < 0 || logicalIndex >= count()) return -1; QSize size = sectionSizeFromContents(logicalIndex); return orientation() == Qt::Horizontal ? size.width() : size.height();}/*! Returns the visual index of the section that covers the given \a position in the viewport. \sa logicalIndexAt()*/int QHeaderView::visualIndexAt(int position) const{ Q_D(const QHeaderView); d->executePostedLayout(); int count = this->count(); if (count < 1) return -1; if (d->reverse()) position = d->viewport->width() - position; position += d->offset; if (position < 0 || position > length()) return -1; int start = 0; int end = count - 1; int visual = (end + 1) / 2; const QVector<QHeaderViewPrivate::HeaderSection> sections = d->sections; while (end - start > 0) { if (sections.at(visual).position > position) end = visual - 1; else start = visual; visual = (start + end + 1) / 2; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -