📄 qlistview.cpp
字号:
return selectionRegion;}/*! \reimp*/QModelIndexList QListView::selectedIndexes() const{ Q_D(const QListView); QModelIndexList viewSelected; QModelIndexList modelSelected; if (selectionModel()) modelSelected = selectionModel()->selectedIndexes(); for (int i = 0; i < modelSelected.count(); ++i) { QModelIndex index = modelSelected.at(i); if (!isIndexHidden(index) && index.parent() == rootIndex() && index.column() == d->column) viewSelected.append(index); } return viewSelected;}/*! \internal Layout the items according to the flow and wrapping properties.*/void QListView::doItemsLayout(){ Q_D(QListView); d->layoutChildren(); // make sure the viewport has the right size d->prepareItemsLayout(); if (model() && model()->columnCount(rootIndex()) > 0) { // no columns means no contents if (layoutMode() == SinglePass) d->doItemsLayout(model()->rowCount(rootIndex())); // layout everything else if (!d->batchLayoutTimer.isActive()) d->batchLayoutTimer.start(0, this); // do a new batch as fast as possible } QAbstractItemView::doItemsLayout();}/*! \internal*/void QListView::updateGeometries(){ Q_D(QListView); if (!model() || model()->rowCount(rootIndex()) <= 0 || model()->columnCount(rootIndex()) <= 0) { horizontalScrollBar()->setRange(0, 0); verticalScrollBar()->setRange(0, 0); } else { QModelIndex index = model()->index(0, d->column, rootIndex()); QStyleOptionViewItem option = viewOptions(); QSize step = d->itemSize(option, index); QSize vsize = d->viewport->size(); QSize max = maximumViewportSize(); if (max.width() >= d->contentsSize.width() && max.height() >= d->contentsSize.height()) vsize = max; horizontalScrollBar()->setSingleStep(step.width() + d->spacing); horizontalScrollBar()->setPageStep(vsize.width()); horizontalScrollBar()->setRange(0, d->contentsSize.width() - vsize.width()); verticalScrollBar()->setSingleStep(step.height() + d->spacing); verticalScrollBar()->setPageStep(vsize.height()); verticalScrollBar()->setRange(0, d->contentsSize.height() - vsize.height()); } // if the scrollbars are turned off, we resize the contents to the viewport if (d->movement == Static && !d->wrap) { if (d->flow == TopToBottom) { if (horizontalScrollBarPolicy() == Qt::ScrollBarAlwaysOff) resizeContents(viewport()->width(), contentsSize().height()); } else { // LeftToRight if (verticalScrollBarPolicy() == Qt::ScrollBarAlwaysOff) resizeContents(contentsSize().width(), viewport()->height()); } } QAbstractItemView::updateGeometries();}/*! \reimp*/bool QListView::isIndexHidden(const QModelIndex &index) const{ Q_D(const QListView); return (d->hiddenRows.contains(index.row()) && (index.parent() == rootIndex()) && index.column() == d->column);}/*! \property QListView::modelColumn \brief the column in the model that is visible*/void QListView::setModelColumn(int column){ Q_D(QListView); if (column < 0 || !model() || column >= model()->columnCount(rootIndex())) return; d->column = column; d->doDelayedItemsLayout();}int QListView::modelColumn() const{ Q_D(const QListView); return d->column;}/*! \property QListView::uniformItemSizes \brief whether all items in the listview have the same size \since 4.1 This property should only be set to true if it is guaranteed that all items in the view have the same size. This enables the view to do some optimizations.*/void QListView::setUniformItemSizes(bool enable){ Q_D(QListView); d->uniformItemSizes = enable;}bool QListView::uniformItemSizes() const{ Q_D(const QListView); return d->uniformItemSizes;}/* \reimp */bool QListView::event(QEvent *e){ return QAbstractItemView::event(e);}/* * private object implementation */QListViewPrivate::QListViewPrivate() : QAbstractItemViewPrivate(), layoutMode(QListView::SinglePass), modeProperties(0), batchStartRow(0), batchSavedDeltaSeg(0), batchSavedPosition(0), column(0), uniformItemSizes(false){}void QListViewPrivate::clear(){ // initialization of data structs batchStartRow = 0; batchSavedPosition = 0; batchSavedDeltaSeg = 0; cachedItemSize = QSize(); tree.destroy(); items.clear(); flowPositions.clear(); segmentPositions.clear(); segmentStartRows.clear();}void QListViewPrivate::prepareItemsLayout(){ Q_Q(QListView); clear(); layoutBounds = viewport->rect(); if (resizeMode == QListView::Adjust) { int verticalMargin = q->style()->pixelMetric(QStyle::PM_ScrollBarExtent, 0, q->verticalScrollBar()); int dw = q->verticalScrollBar()->isVisible() ? 0 : verticalMargin; int horizontalMargin = q->style()->pixelMetric(QStyle::PM_ScrollBarExtent, 0, q->horizontalScrollBar()); int dh = q->horizontalScrollBar()->isVisible() ? 0 : horizontalMargin; layoutBounds.adjust(0, 0, -dw, -dh); } int rowCount = model ? model->rowCount(root) : 0; int colCount = model ? model->columnCount(root) : 0; if (colCount <= 0) rowCount = 0; // no contents if (movement == QListView::Static) { flowPositions.resize(rowCount); } else { tree.create(qMax(rowCount - hiddenRows.count(), 0)); }}QPoint QListViewPrivate::initStaticLayout(const QRect &bounds, int spacing, int first){ int x, y; if (first == 0) { flowPositions.clear(); segmentPositions.clear(); segmentStartRows.clear(); x = bounds.left() + spacing; y = bounds.top() + spacing; segmentPositions.append(flow == QListView::LeftToRight ? y : x); segmentStartRows.append(0); } else if (wrap) { if (flow == QListView::LeftToRight) { x = batchSavedPosition; y = segmentPositions.last(); } else { // flow == QListView::TopToBottom x = segmentPositions.last(); y = batchSavedPosition; } } else { // not first and not wrap if (flow == QListView::LeftToRight) { x = batchSavedPosition; y = bounds.top() + spacing; } else { // flow == QListView::TopToBottom x = bounds.left() + spacing; y = batchSavedPosition; } } return QPoint(x, y);}QPoint QListViewPrivate::initDynamicLayout(const QRect &bounds, int spacing, int first){ int x, y; if (first == 0) { x = bounds.x() + spacing; y = bounds.y() + spacing; items.reserve(model->rowCount(root) - hiddenRows.count()); } else { const QListViewItem item = items.at(first - 1); x = item.x; y = item.y; if (flow == QListView::LeftToRight) x += (gridSize.isValid() ? gridSize.width() : item.w) + spacing; else y += (gridSize.isValid() ? gridSize.height() : item.h) + spacing; } return QPoint(x, y);}void QListViewPrivate::initBspTree(const QSize &contents){ // remove all items from the tree int leafCount = tree.leafCount(); for (int l = 0; l < leafCount; ++l) tree.leaf(l).clear(); // we have to get the bounding rect of the items before we can initialize the tree QBspTree::Node::Type type = QBspTree::Node::Both; // 2D // simple heuristics to get better bsp if (contents.height() / contents.width() >= 3) type = QBspTree::Node::HorizontalPlane; else if (contents.width() / contents.height() >= 3) type = QBspTree::Node::VerticalPlane; // build tree for the bounding rect (not just the contents rect) tree.init(QRect(0, 0, contents.width(), contents.height()), type);}/*! \internal*/bool QListViewPrivate::doItemsLayout(int delta){ int max = model->rowCount(root) - 1; int first = batchStartRow; int last = qMin(first + delta - 1, max); if (max < 0) return true; // nothing to do if (movement == QListView::Static) { doStaticLayout(layoutBounds, first, last); } else { if (last >= items.count()) createItems(last + 1); doDynamicLayout(layoutBounds, first, last); } if (batchStartRow >= max) { // stop items layout flowPositions.resize(flowPositions.count()); segmentPositions.resize(segmentPositions.count()); segmentStartRows.resize(segmentStartRows.count()); return true; // done } return false; // not done}/*! \internal*/void QListViewPrivate::doItemsLayout(const QRect &bounds, const QModelIndex &first, const QModelIndex &last){ if (first.row() >= last.row() || !first.isValid() || !last.isValid()) return; if (movement == QListView::Static) doStaticLayout(bounds, first.row(), last.row()); else doDynamicLayout(bounds, first.row(), last.row());}/*! \internal*/void QListViewPrivate::doStaticLayout(const QRect &bounds, int first, int last){ Q_Q(QListView); const bool useItemSize = !gridSize.isValid(); const int gap = useItemSize ? spacing : 0; // if we are using a grid ,we don't use spacing const QPoint topLeft = initStaticLayout(bounds, gap, first); const QStyleOptionViewItem option = q->viewOptions(); // The static layout data structures are as follows: // One vector contains the coordinate in the direction of layout flow. // Another vector contains the coordinates of the segments. // A third vector contains the index (model row) of the first item // of each segment. int segStartPosition; int segEndPosition; int deltaFlowPosition; int deltaSegPosition; int deltaSegHint; int flowPosition; int segPosition; if (flow == QListView::LeftToRight) { segStartPosition = bounds.left(); segEndPosition = bounds.width(); flowPosition = topLeft.x(); segPosition = topLeft.y(); deltaFlowPosition = gridSize.width(); // dx deltaSegPosition = useItemSize ? batchSavedDeltaSeg : gridSize.height(); // dy deltaSegHint = gridSize.height(); } else { // flow == QListView::TopToBottom segStartPosition = bounds.top(); segEndPosition = bounds.height(); flowPosition = topLeft.y(); segPosition = topLeft.x(); deltaFlowPosition = gridSize.height(); // dy deltaSegPosition = useItemSize ? batchSavedDeltaSeg : gridSize.width(); // dx deltaSegHint = gridSize.width(); } for (int row = first; row <= last; ++row) { if (hiddenRows.contains(row)) { flowPositions.append(flowPosition); } else { // if we are not using a grid, we need to find the deltas if (useItemSize) { QSize hint = itemSize(option, model->index(row, column, root)); if (flow == QListView::LeftToRight) { deltaFlowPosition = hint.width() + gap; deltaSegHint = hint.height() + gap; } else { // TopToBottom deltaFlowPosition = hint.height() + gap; deltaSegHint = hint.width() + gap; } } // create new segment if (wrap && (flowPosition + deltaFlowPosition >= segEndPosition)) { flowPosition = gap + segStartPosition; segPosition += deltaSegPosition; segmentPositions.append(segPosition); segmentStartRows.append(row); deltaSegPosition = 0; } // save the flow positon of this item flowPositions.append(flowPosition); // prepare for the next item deltaSegPosition = qMax(deltaSegHint, deltaSegPosition); flowPosition += gap + deltaFlowPosition; } } // used when laying out next batch batchSavedPosition = flowPosition; batchSavedDeltaSeg = deltaSegPosition; batchStartRow = last + 1; // set the contents size QRect rect = bounds; if (flow == QListView::LeftToRight) { rect.setRight(segmentPositions.count() == 1 ? flowPosition : bounds.right()); rect.setBottom(segPosition + deltaSegPosition); } else { // TopToBottom rect.setRight(segPosition + deltaSegPosition); rect.setBottom(segmentPositions.count() == 1 ? flowPosition : bounds.bottom()); } q->resizeContents(rect.right(), rect.bottom()); // if the new items are visble, update the viewport QRect changedRect(topLeft, rect.bottomRight()); if (clipRect().intersects(changedRect)) viewport->update();}/*! \internal*/void QListViewPrivate::doDynamicLayout(const QRect &bounds, int first, int last)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -