📄 qtableview.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 "qtableview.h"#ifndef QT_NO_TABLEVIEW#include <qheaderview.h>#include <qitemdelegate.h>#include <qapplication.h>#include <qpainter.h>#include <qstyle.h>#include <qsize.h>#include <qevent.h>#include <qscrollbar.h>#include <private/qtableview_p.h>void QTableViewPrivate::init(){ Q_Q(QTableView); q->setEditTriggers(editTriggers|QAbstractItemView::AnyKeyPressed); QHeaderView *vertical = new QHeaderView(Qt::Vertical, q); vertical->setClickable(true); vertical->setHighlightSections(true); q->setVerticalHeader(vertical); QHeaderView *horizontal = new QHeaderView(Qt::Horizontal, q); horizontal->setClickable(true); horizontal->setHighlightSections(true); q->setHorizontalHeader(horizontal); tabKeyNavigation = true;}/*! \internal Trims away indices that are hidden in the treeview due to hidden horizontal or vertical sections.*/void QTableViewPrivate::trimHiddenSelections(QItemSelectionRange *range) const{ Q_ASSERT(model); Q_ASSERT(range && range->isValid()); int top = range->top(); int left = range->left(); int bottom = range->bottom(); int right = range->right(); while (bottom >= top && verticalHeader->isSectionHidden(bottom)) --bottom; while (right >= left && horizontalHeader->isSectionHidden(right)) --right; if (top > bottom || left > right) { // everything is hidden *range = QItemSelectionRange(); return; } while (verticalHeader->isSectionHidden(top) && top <= bottom) ++top; while (horizontalHeader->isSectionHidden(left) && left <= right) ++left; if (top > bottom || left > right) { // everything is hidden *range = QItemSelectionRange(); return; } QModelIndex bottomRight = model->index(bottom, right, range->parent()); QModelIndex topLeft = model->index(top, left, range->parent()); *range = QItemSelectionRange(topLeft, bottomRight);}/*! \class QTableView qtableview.h \brief The QTableView class provides a default model/view implementation of a table view. \ingroup model-view \mainclass A QTableView implements a table view that displays items from a model. This class is used to provide standard tables that were previously provided by the QTable class, but using the more flexible approach provided by Qt's model/view architecture. The QTableView class is one of the \l{Model/View Classes} and is part of Qt's \l{Model/View Programming}{model/view framework}. QTableView implements the interfaces defined by the QAbstractItemView class to allow it to display data provided by models derived from the QAbstractItemModel class. The table has a vertical header that can be obtained using the verticalHeader() function, and a horizontal header that is available through the horizontalHeader() function. The height of each row in the table can be found by using rowHeight(); similarly, the width of columns can be found using columnWidth(). They are both just QWidgets so you can hide either of them using their hide() functions. Rows and columns can be hidden and shown with hideRow(), hideColumn(), showRow(), and showColumn(). They can be selected with selectRow() and selectColumn(). The table will show a grid depending on the \l showGrid property. For some specialized forms of tables it is useful to be able to convert between row and column indexes and widget coordinates. The rowAt() function provides the y-coordinate within the view of the specified row; the row index can be used to obtain a corresponding y-coordinate with rowViewportPosition(). The columnAt() and columnViewportPosition() functions provide the equivalent conversion operations between x-coordinates and column indexes. \table 100% \row \o \inlineimage windowsxp-tableview.png Screenshot of a Windows XP style table view \o \inlineimage macintosh-tableview.png Screenshot of a Macintosh style table view \o \inlineimage plastique-tableview.png Screenshot of a Plastique style table view \row \o A \l{Windows XP Style Widget Gallery}{Windows XP style} table view. \o A \l{Macintosh Style Widget Gallery}{Macintosh style} table view. \o A \l{Plastique Style Widget Gallery}{Plastique style} table view. \endtable \sa QTableWidget, {Model/View Programming}, QAbstractItemModel, QAbstractItemView*//*! Constructs a table view with a \a parent to represent the data. \sa QAbstractItemModel*/QTableView::QTableView(QWidget *parent) : QAbstractItemView(*new QTableViewPrivate, parent){ d_func()->init();}/*! \internal*/QTableView::QTableView(QTableViewPrivate &dd, QWidget *parent) : QAbstractItemView(dd, parent){ d_func()->init();}/*! Destroys the table view.*/QTableView::~QTableView(){}/*! \reimp*/void QTableView::setModel(QAbstractItemModel *model){ Q_D(QTableView); d->verticalHeader->setModel(model); d->horizontalHeader->setModel(model); QAbstractItemView::setModel(model);}/*! \reimp*/void QTableView::setRootIndex(const QModelIndex &index){ Q_D(QTableView); d->verticalHeader->setRootIndex(index); d->horizontalHeader->setRootIndex(index); QAbstractItemView::setRootIndex(index);}/*! \reimp*/void QTableView::setSelectionModel(QItemSelectionModel *selectionModel){ Q_D(QTableView); Q_ASSERT(selectionModel); d->verticalHeader->setSelectionModel(selectionModel); d->horizontalHeader->setSelectionModel(selectionModel); QAbstractItemView::setSelectionModel(selectionModel);}/*! Returns the table view's horizontal header. \sa setHorizontalHeader(), verticalHeader(), QAbstractItemModel::headerData()*/QHeaderView *QTableView::horizontalHeader() const{ return d_func()->horizontalHeader;}/*! Returns the table view's vertical header. \sa setVerticalHeader(), horizontalHeader(), QAbstractItemModel::headerData()*/QHeaderView *QTableView::verticalHeader() const{ return d_func()->verticalHeader;}/*! Sets the widget to use for the vertical header to \a header. \sa horizontalHeader() setVerticalHeader()*/void QTableView::setHorizontalHeader(QHeaderView *header){ Q_D(QTableView); Q_ASSERT(header); if (header == d->horizontalHeader) return; if (d->horizontalHeader && d->horizontalHeader->parent() == this) delete d->horizontalHeader; d->horizontalHeader = header; d->horizontalHeader->setParent(this); if (!d->horizontalHeader->model()) d->horizontalHeader->setModel(model()); connect(d->horizontalHeader,SIGNAL(sectionResized(int,int,int)), this, SLOT(columnResized(int,int,int))); connect(d->horizontalHeader, SIGNAL(sectionMoved(int,int,int)), this, SLOT(columnMoved(int,int,int))); connect(d->horizontalHeader, SIGNAL(sectionCountChanged(int,int)), this, SLOT(columnCountChanged(int,int))); connect(d->horizontalHeader, SIGNAL(sectionPressed(int)), this, SLOT(selectColumn(int))); connect(d->horizontalHeader, SIGNAL(sectionHandleDoubleClicked(int)), this, SLOT(resizeColumnToContents(int))); d->horizontalHeader->setFocusProxy(this);}/*! Sets the widget to use for the horizontal header to \a header. \sa verticalHeader() setHorizontalHeader()*/void QTableView::setVerticalHeader(QHeaderView *header){ Q_D(QTableView); Q_ASSERT(header); if (header == d->verticalHeader) return; if (d->verticalHeader && d->verticalHeader->parent() == this) delete d->verticalHeader; d->verticalHeader = header; d->verticalHeader->setParent(this); if (!d->verticalHeader->model()) d->verticalHeader->setModel(model()); connect(d->verticalHeader, SIGNAL(sectionResized(int,int,int)), this, SLOT(rowResized(int,int,int))); connect(d->verticalHeader, SIGNAL(sectionMoved(int,int,int)), this, SLOT(rowMoved(int,int,int))); connect(d->verticalHeader, SIGNAL(sectionCountChanged(int,int)), this, SLOT(rowCountChanged(int,int))); connect(d->verticalHeader, SIGNAL(sectionPressed(int)), this, SLOT(selectRow(int))); connect(d->verticalHeader, SIGNAL(sectionHandleDoubleClicked(int)), this, SLOT(resizeRowToContents(int))); d->verticalHeader->setFocusProxy(this);}/*! \internal Scroll the contents of the table view by \a(dx, dy).*/void QTableView::scrollContentsBy(int dx, int dy){ Q_D(QTableView); dx = isRightToLeft() ? -dx : dx; if (dx) d->horizontalHeader->setOffset(horizontalScrollBar()->value()); if (dy) d->verticalHeader->setOffset(verticalScrollBar()->value()); d->scrollContentsBy(dx, dy);}/*! \reimp*/QStyleOptionViewItem QTableView::viewOptions() const{ QStyleOptionViewItem option = QAbstractItemView::viewOptions(); option.showDecorationSelected = true; return option;}/*! Paints the table on receipt of the given paint event \a event.*/void QTableView::paintEvent(QPaintEvent *event){ Q_D(QTableView); // setup temp variables for the painting QStyleOptionViewItem option = viewOptions(); const QPoint offset = d->scrollDelayOffset; const bool showGrid = d->showGrid; const int gridSize = showGrid ? 1 : 0; const int gridHint = style()->styleHint(QStyle::SH_Table_GridLineColor, &option, this); const QColor gridColor = static_cast<QRgb>(gridHint); const QPen gridPen = QPen(gridColor, 0, d->gridStyle); const QItemSelectionModel *sels = selectionModel(); const QHeaderView *verticalHeader = d->verticalHeader; const QHeaderView *horizontalHeader = d->horizontalHeader; const QModelIndex current = currentIndex(); const QModelIndex hover = d->hover; const bool focus = (hasFocus() || d->viewport->hasFocus()) && current.isValid(); const QStyle::State state = option.state; const bool alternate = d->alternatingColors; const bool enabled = (state & QStyle::State_Enabled) != 0; QPainter painter(d->viewport); // if there's nothing to do, clear the area and return if (!model() || horizontalHeader->count() == 0 || verticalHeader->count() == 0) { painter.fillRect(event->rect(), option.palette.brush(QPalette::Base)); return; } QVector<QRect> rects = event->region().rects(); for (int i = 0; i < rects.size(); ++i) { QRect area = rects.at(i); area.translate(offset); // get the horizontal start and end sections (visual indexes) int left = horizontalHeader->visualIndexAt(area.left()); int right = horizontalHeader->visualIndexAt(area.right()); if (isRightToLeft()) { if (left == -1) left = horizontalHeader->count() - 1; if (right == -1) right = 0; } else { if (left == -1) left = 0; if (right == -1) right = horizontalHeader->count() - 1; } int tmp = left; left = qMin(left, right); right = qMax(tmp, right);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -