📄 qtableview.cpp
字号:
if (index == q->currentIndex()) { const bool focus = (q->hasFocus() || viewport->hasFocus()) && q->currentIndex().isValid(); if (focus) opt.state |= QStyle::State_HasFocus; } if (opt.features & QStyleOptionViewItemV2::Alternate) painter->fillRect(opt.rect, opt.palette.brush(QPalette::AlternateBase)); if (const QWidget *widget = editorForIndex(index)) { painter->save(); painter->setClipRect(widget->geometry()); q->itemDelegate(index)->paint(painter, opt, index); painter->restore(); } else { q->itemDelegate(index)->paint(painter, opt, index); }}/*! \class QTableView \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}. You can navigate the cells in the table by clicking on a cell with the mouse, or by using the arrow keys. Because QTableView enables \l{QAbstractItemView::tabKeyNavigation}{tabKeyNavigation} by default, you can also hit Tab and Backtab to move from cell to cell. 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. The items shown in a table view, like those in the other item views, are rendered and edited using standard \l{QItemDelegate}{delegates}. However, for some tasks it is sometimes useful to be able to insert widgets in a table instead. Widgets are set for particular indexes with the \l{QAbstractItemView::}{setIndexWidget()} function, and later retrieved with \l{QAbstractItemView::}{indexWidget()}. 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, {View Classes}, QAbstractItemModel, QAbstractItemView, {Chart Example}, {Pixelator Example}, {Table Model Example}*//*! Constructs a table view with a \a parent to represent the data. \sa QAbstractItemModel*/QTableView::QTableView(QWidget *parent) : QAbstractItemView(*new QTableViewPrivate, parent){ Q_D(QTableView); d->init();}/*! \internal*/QTableView::QTableView(QTableViewPrivate &dd, QWidget *parent) : QAbstractItemView(dd, parent){ Q_D(QTableView); d->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); if (index == d->root) { viewport()->update(); return; } 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{ Q_D(const QTableView); return d->horizontalHeader;}/*! Returns the table view's vertical header. \sa setVerticalHeader(), horizontalHeader(), QAbstractItemModel::headerData()*/QHeaderView *QTableView::verticalHeader() const{ Q_D(const QTableView); return d->verticalHeader;}/*! Sets the widget to use for the vertical header to \a header. \sa horizontalHeader() setVerticalHeader()*/void QTableView::setHorizontalHeader(QHeaderView *header){ Q_D(QTableView); if (!header || 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(d->model); if (d->selectionModel) d->horizontalHeader->setSelectionModel(d->selectionModel); } 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(sectionEntered(int)), this, SLOT(_q_selectColumn(int))); connect(d->horizontalHeader, SIGNAL(sectionHandleDoubleClicked(int)), this, SLOT(resizeColumnToContents(int))); connect(d->horizontalHeader, SIGNAL(geometriesChanged()), this, SLOT(updateGeometries()));}/*! Sets the widget to use for the horizontal header to \a header. \sa verticalHeader() setHorizontalHeader()*/void QTableView::setVerticalHeader(QHeaderView *header){ Q_D(QTableView); if (!header || 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(d->model); if (d->selectionModel) d->verticalHeader->setSelectionModel(d->selectionModel); } 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(sectionEntered(int)), this, SLOT(_q_selectRow(int))); connect(d->verticalHeader, SIGNAL(sectionHandleDoubleClicked(int)), this, SLOT(resizeRowToContents(int))); connect(d->verticalHeader, SIGNAL(geometriesChanged()), this, SLOT(updateGeometries()));}/*! \internal Scroll the contents of the table view by (\a dx, \a dy).*/void QTableView::scrollContentsBy(int dx, int dy){ Q_D(QTableView); d->delayedAutoScroll.stop(); // auto scroll was canceled by the user scrolling dx = isRightToLeft() ? -dx : dx; if (dx) { if (horizontalScrollMode() == QAbstractItemView::ScrollPerItem) { int oldOffset = d->horizontalHeader->offset(); if (horizontalScrollBar()->value() == horizontalScrollBar()->maximum()) d->horizontalHeader->setOffsetToLastSection(); else d->horizontalHeader->setOffsetToSectionPosition(horizontalScrollBar()->value()); int newOffset = d->horizontalHeader->offset(); dx = isRightToLeft() ? newOffset - oldOffset : oldOffset - newOffset; } else { d->horizontalHeader->setOffset(horizontalScrollBar()->value()); } } if (dy) { if (verticalScrollMode() == QAbstractItemView::ScrollPerItem) { int oldOffset = d->verticalHeader->offset(); if (verticalScrollBar()->value() == verticalScrollBar()->maximum()) d->verticalHeader->setOffsetToLastSection(); else d->verticalHeader->setOffsetToSectionPosition(verticalScrollBar()->value()); int newOffset = d->verticalHeader->offset(); dy = oldOffset - newOffset; } else { 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 QStyleOptionViewItemV3 option = d->viewOptionsV3(); 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 QHeaderView *verticalHeader = d->verticalHeader; const QHeaderView *horizontalHeader = d->horizontalHeader; const QStyle::State state = option.state; const bool alternate = d->alternatingColors; const bool rightToLeft = isRightToLeft(); const int columnCount = d->model->columnCount(d->root); QPainter painter(d->viewport); // if there's nothing to do, clear the area and return if (horizontalHeader->count() == 0 || verticalHeader->count() == 0 || !d->itemDelegate) return; uint x = horizontalHeader->length() - horizontalHeader->offset() - 1; uint y = verticalHeader->length() - verticalHeader->offset() - 1; QVector<QRect> rects = event->region().rects(); for (int i = 0; i < rects.size(); ++i) { QRect dirtyArea = rects.at(i); dirtyArea.translate(offset); dirtyArea.setBottom(qMin((uint)dirtyArea.bottom(), y)); if (rightToLeft) { dirtyArea.setLeft(qMax((uint)dirtyArea.left(), d->viewport->width() - x)); } else { dirtyArea.setRight(qMin((uint)dirtyArea.right(), x)); } QBitArray paintedCells; if (d->hasSpans()) paintedCells = d->drawAndClipSpans(dirtyArea, &painter, option); // get the horizontal start and end visual sections int left = horizontalHeader->visualIndexAt(dirtyArea.left()); int right = horizontalHeader->visualIndexAt(dirtyArea.right()); if (rightToLeft) qSwap(left, right); if (left == -1) left = 0; if (right == -1) right = horizontalHeader->count() - 1; // get the vertical start and end visual sections and if alternate color int bottom = verticalHeader->visualIndexAt(dirtyArea.bottom()); if (bottom == -1) bottom = verticalHeader->count() - 1; int top = 0; bool alternateBase = false; if (alternate && verticalHeader->sectionsHidden()) { uint verticalOffset = verticalHeader->offset(); int row = verticalHeader->logicalIndex(top); for (int y = 0; ((uint)(y += verticalHeader->sectionSize(top)) <= verticalOffset) && (top < bottom); ++top) { row = verticalHeader->logicalIndex(top); if (alternate && !verticalHeader->isSectionHidden(row)) alternateBase = !alternateBase; } } else { top = verticalHeader->visualIndexAt(dirtyArea.top()); alternateBase = (top & 1) && alternate; } if (top == -1 || top > bottom) continue; // Paint each row item for (int visualIndex = top; visualIndex <= bottom; ++visualIndex) { int row = verticalHeader->logicalIndex(visualIndex); if (verticalHeader->isSectionHidden(row)) continue; int rowY = rowViewportPosition(row); rowY += offset.y(); int rowh = rowHeight(row) - gridSize; // Paint each column item for (int h = left; h <= right; ++h) { int col = horizontalHeader->logicalIndex(h); if (horizontalHeader->isSectionHidden(col))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -