⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qabstractscrollarea.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/******************************************************************************** Copyright (C) 1992-2007 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://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** 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 "qabstractscrollarea.h"#ifndef QT_NO_SCROLLAREA#include "qscrollbar.h"#include "qapplication.h"#include "qstyle.h"#include "qstyleoption.h"#include "qevent.h"#include "qdebug.h"#include "qboxlayout.h"#include "qpainter.h"#include "qabstractscrollarea_p.h"#include <qwidget.h>#ifdef Q_WS_MAC#include <qmacstyle_mac.h>#include <private/qt_mac_p.h>#endif/*!    \class QAbstractScrollArea    \brief The QAbstractScrollArea widget provides a scrolling area with    on-demand scroll bars.    \ingroup abstractwidgets    QAbstractScrollArea is a low-level abstraction of a scrolling    area. The area provides a central widget called the viewport, in    which the contents of the area is to be scrolled (i.e, the    visible parts of the contents are rendered in the viewport).     Next to the viewport is a vertical scroll bar, and below is a    horizontal scroll bar. When all of the area contents fits in the    viewport, each scroll bar can be either visible or hidden    depending on the scroll bar's Qt::ScrollBarPolicy. When a scroll    bar is hidden, the viewport expands in order to cover all    available space. When a scroll bar becomes visible again, the    viewport shrinks in order to make room for the scroll bar.    It is possible to reserve a margin area around the viewport, see    setViewportMargins(). The feature is mostly used to place a    QHeaderView widget above or beside the scrolling area. Subclasses    of QAbstractScrollArea should implement margins.    When inheriting QAbstractScrollArea, you need to do the    following:    \list        \o Control the scroll bars by setting their           range, value, page step, and tracking their           movements.        \o Draw the contents of the area in the viewport according           to the values of the scroll bars.        \o Handle events received by the viewport in           viewportEvent() - notably resize events.    \endlist    With a scroll bar policy of Qt::ScrollBarAsNeeded (the default),    QAbstractScrollArea shows scroll bars when they provide a non-zero    scrolling range, and hides them otherwise.    The scroll bars and viewport should be updated whenever the viewport    receives a resize event or the size of the contents changes.    The viewport also needs to be updated when the scroll bars    values change. The initial values of the scroll bars are often    set when the area receives new contents.     We give a simple example, in which we have implemented a scroll area    that can scroll any QWidget. We make the widget a child of the    viewport; this way, we do not have to calculate which part of    the widget to draw but can simply move the widget with    QWidget::move(). When the area contents or the viewport size    changes, we do the following:     \quotefromfile snippets/myscrollarea.cpp    \skipto areaSize    \printto /^\}/    When the scroll bars change value, we need to update the widget    position, i.e., find the part of the widget that is to be drawn in    the viewport:    \quotefromfile snippets/myscrollarea.cpp    \skipto hvalue    \printto /^\}/    In order to track scroll bar movements, reimplement the virtual    function scrollContentsBy(). In order to fine-tune scrolling    behavior, connect to a scroll bar's    QAbstractSlider::actionTriggered() signal and adjust the \l    QAbstractSlider::sliderPosition as you wish.    For convenience, QAbstractScrollArea makes all viewport events    available in the virtual viewportEvent() handler. QWidget's    specialized handlers are remapped to viewport events in the cases    where this makes sense. The remapped specialized handlers are:    paintEvent(), mousePressEvent(), mouseReleaseEvent(),    mouseDoubleClickEvent(), mouseMoveEvent(), wheelEvent(),    dragEnterEvent(), dragMoveEvent(), dragLeaveEvent(), dropEvent(),    contextMenuEvent(),  and resizeEvent().    QScrollArea, which inherits QAbstractScrollArea, provides smooth    scrolling for any QWidget (i.e., the widget is scrolled pixel by    pixel). You only need to subclass QAbstractScrollArea if you need    more specialized behavior. This is, for instance, true if the    entire contents of the area is not suitable for being drawn on a    QWidget or if you do not want smooth scrolling.    \sa QScrollArea*/QAbstractScrollAreaPrivate::QAbstractScrollAreaPrivate()    :hbar(0), vbar(0), vbarpolicy(Qt::ScrollBarAsNeeded), hbarpolicy(Qt::ScrollBarAsNeeded),     viewport(0), cornerWidget(0), left(0), top(0), right(0), bottom(0),     xoffset(0), yoffset(0), viewportFilter(0){}QAbstractScrollAreaScrollBarContainer::QAbstractScrollAreaScrollBarContainer(Qt::Orientation orientation, QWidget *parent)    :QWidget(parent), scrollBar(new QScrollBar(orientation, this)),     layout(new QBoxLayout(orientation == Qt::Horizontal ? QBoxLayout::LeftToRight : QBoxLayout::TopToBottom)),     orientation(orientation){    setLayout(layout);    layout->setMargin(0);    layout->setSpacing(0);    layout->addWidget(scrollBar);}/*! \internal    Adds a widget to the scroll bar container.*/void QAbstractScrollAreaScrollBarContainer::addWidget(QWidget *widget, LogicalPosition position){    QSizePolicy policy = widget->sizePolicy();    if (orientation == Qt::Vertical)        policy.setHorizontalPolicy(QSizePolicy::Ignored);    else        policy.setVerticalPolicy(QSizePolicy::Ignored);    widget->setSizePolicy(policy);    widget->setParent(this);    const int insertIndex = (position & LogicalLeft) ? 0 : scrollBarLayoutIndex() + 1;    layout->insertWidget(insertIndex, widget);}/*! \internal    Retuns a list of scroll bar widgets for the given position. The scroll bar    itself is not returned.*/QWidgetList QAbstractScrollAreaScrollBarContainer::widgets(LogicalPosition position){    QWidgetList list;    const int scrollBarIndex = scrollBarLayoutIndex();    if (position == LogicalLeft) {        for (int i = 0; i < scrollBarIndex; ++i)            list.append(layout->itemAt(i)->widget());    } else if (position == LogicalRight) {        const int layoutItemCount = layout->count();        for (int i = scrollBarIndex + 1; i < layoutItemCount; ++i)            list.append(layout->itemAt(i)->widget());    }    return list;}/*! \internal    Returns the layout index for the scroll bar. This needs to be    recalculated by a linear search for each use, since items in    the layout can be removed at any time (i.e. when a widget is    deleted or re-parented).*/int QAbstractScrollAreaScrollBarContainer::scrollBarLayoutIndex() const{    const int layoutItemCount = layout->count();    for (int i = 0; i < layoutItemCount; ++i) {        if (qobject_cast<QScrollBar *>(layout->itemAt(i)->widget()))            return i;    }    return -1;}/*! \internal*/void QAbstractScrollAreaPrivate::replaceScrollBar(QScrollBar *scrollBar,                                                  Qt::Orientation orientation){    Q_Q(QAbstractScrollArea);    QAbstractScrollAreaScrollBarContainer *container = scrollBarContainers[orientation];    bool horizontal = (orientation == Qt::Horizontal);    QScrollBar *oldBar = horizontal ? hbar : vbar;    if (horizontal)        hbar = scrollBar;    else        vbar = scrollBar;    scrollBar->setParent(container);    container->scrollBar = scrollBar;    container->layout->removeWidget(oldBar);    container->layout->insertWidget(0, scrollBar);    scrollBar->setVisible(oldBar->isVisibleTo(oldBar->window()));    scrollBar->setInvertedAppearance(oldBar->invertedAppearance());    scrollBar->setInvertedControls(oldBar->invertedControls());    scrollBar->setRange(oldBar->minimum(), oldBar->maximum());    scrollBar->setOrientation(oldBar->orientation());    scrollBar->setPageStep(oldBar->pageStep());    scrollBar->setSingleStep(oldBar->singleStep());    scrollBar->setSliderDown(oldBar->isSliderDown());    scrollBar->setSliderPosition(oldBar->sliderPosition());    scrollBar->setTracking(oldBar->hasTracking());    scrollBar->setValue(oldBar->value());    delete oldBar;    QObject::connect(scrollBar, SIGNAL(valueChanged(int)),                     q, horizontal ? SLOT(_q_hslide(int)) : SLOT(_q_vslide(int)));    QObject::connect(scrollBar, SIGNAL(rangeChanged(int,int)),                     q, SLOT(_q_showOrHideScrollBars()), Qt::QueuedConnection);}void QAbstractScrollAreaPrivate::init(){    Q_Q(QAbstractScrollArea);    scrollBarContainers[Qt::Horizontal] = new QAbstractScrollAreaScrollBarContainer(Qt::Horizontal, q);    scrollBarContainers[Qt::Horizontal]->setObjectName(QLatin1String("qt_scrollarea_hcontainer"));    hbar = scrollBarContainers[Qt::Horizontal]->scrollBar;    hbar->setRange(0,0);    scrollBarContainers[Qt::Horizontal]->setVisible(false);    QObject::connect(hbar, SIGNAL(valueChanged(int)), q, SLOT(_q_hslide(int)));    QObject::connect(hbar, SIGNAL(rangeChanged(int,int)), q, SLOT(_q_showOrHideScrollBars()), Qt::QueuedConnection);    scrollBarContainers[Qt::Vertical] = new QAbstractScrollAreaScrollBarContainer(Qt::Vertical, q);    scrollBarContainers[Qt::Vertical]->setObjectName(QLatin1String("qt_scrollarea_vcontainer"));    vbar = scrollBarContainers[Qt::Vertical]->scrollBar;    vbar->setRange(0,0);    scrollBarContainers[Qt::Vertical]->setVisible(false);    QObject::connect(vbar, SIGNAL(valueChanged(int)), q, SLOT(_q_vslide(int)));    QObject::connect(vbar, SIGNAL(rangeChanged(int,int)), q, SLOT(_q_showOrHideScrollBars()), Qt::QueuedConnection);    viewportFilter = new QAbstractScrollAreaFilter(this);    viewport = new QWidget(q);    viewport->setObjectName(QLatin1String("qt_scrollarea_viewport"));    viewport->setBackgroundRole(QPalette::Base);    viewport->setAutoFillBackground(true);    viewport->installEventFilter(viewportFilter);    viewport->setFocusProxy(q);    q->setFocusPolicy(Qt::WheelFocus);    q->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);    q->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);    layoutChildren();}void QAbstractScrollAreaPrivate::layoutChildren(){    Q_Q(QAbstractScrollArea);    bool needh = (hbarpolicy == Qt::ScrollBarAlwaysOn                  || (hbarpolicy == Qt::ScrollBarAsNeeded && hbar->minimum() < hbar->maximum()));    bool needv = (vbarpolicy == Qt::ScrollBarAlwaysOn                  || (vbarpolicy == Qt::ScrollBarAsNeeded && vbar->minimum() < vbar->maximum()));    const int hsbExt = hbar->sizeHint().height();    const int vsbExt = vbar->sizeHint().width();    const QPoint extPoint(vsbExt, hsbExt);    const QSize extSize(vsbExt, hsbExt);    const QRect widgetRect = q->rect();    QStyleOption opt(0);    opt.init(q);    const bool hasCornerWidget = (cornerWidget != 0);// If the scroll bars are at the very right and bottom of the window we// move their positions to be aligned with the size grip.#ifdef Q_WS_MAC    QWidget * const window = q->window();    // Check if a native sizegrip is present.    bool hasMacReverseSizeGrip = false;    bool hasMacSizeGrip = false;    HIViewRef nativeSizeGrip;    HIViewFindByID(HIViewGetRoot(HIViewGetWindow(HIViewRef(q->winId()))), kHIViewWindowGrowBoxID, &nativeSizeGrip);    if (nativeSizeGrip) {        // Look for a native size grip at the visual window bottom right and at the        // absolute window bottom right. In reverse mode, the native size grip does not        // swich side, so we need to check if it is on the "wrong side".        const QPoint scrollAreaBottomRight = q->mapTo(window, widgetRect.bottomRight() - QPoint(frameWidth, frameWidth));        const QPoint windowBottomRight = window->rect().bottomRight();        const QPoint visualWindowBottomRight = QStyle::visualPos(opt.direction, opt.rect, windowBottomRight);        const QPoint offset = windowBottomRight - scrollAreaBottomRight;        const QPoint visualOffset = visualWindowBottomRight - scrollAreaBottomRight;        hasMacSizeGrip = (visualOffset.manhattanLength() < vsbExt);        hasMacReverseSizeGrip = (hasMacSizeGrip == false && (offset.manhattanLength() < hsbExt));    }    // Use small scroll bars for tool windows, to match the native size grip.    const QMacStyle::WidgetSizePolicy hpolicy = QMacStyle::widgetSizePolicy(hbar);    const QMacStyle::WidgetSizePolicy vpolicy = QMacStyle::widgetSizePolicy(vbar);    const Qt::WindowType windowType = window->windowType();    if (windowType == Qt::Tool) {        if (hpolicy != QMacStyle::SizeSmall)            QMacStyle::setWidgetSizePolicy(hbar, QMacStyle::SizeSmall);        if (vpolicy != QMacStyle::SizeSmall)            QMacStyle::setWidgetSizePolicy(vbar, QMacStyle::SizeSmall);    } else {        if (hpolicy != QMacStyle::SizeDefault)            QMacStyle::setWidgetSizePolicy(hbar, QMacStyle::SizeDefault);        if (vpolicy != QMacStyle::SizeDefault)            QMacStyle::setWidgetSizePolicy(vbar, QMacStyle::SizeDefault);    }#endif    QPoint cornerOffset(needv ? vsbExt : 0, needh ? hsbExt : 0);    QRect controlsRect;    QRect viewportRect;    // In FrameOnlyAroundContents mode the frame is drawn between the controls and    // the viewport, else the frame rect is equal to the widget rect.    if (q->style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents, &opt, q)) {        controlsRect = widgetRect;        const int extra = q->style()->pixelMetric(QStyle::PM_DefaultFrameWidth) * 2;        const QPoint cornerExtra(needv ? extra : 0, needh ? extra : 0);        QRect frameRect = widgetRect;        frameRect.adjust(0, 0, -cornerOffset.x() - cornerExtra.x(), -cornerOffset.y() - cornerExtra.y());        q->setFrameRect(frameRect);        viewportRect = q->contentsRect();    } else {        q->setFrameRect(QStyle::visualRect(opt.direction, opt.rect, widgetRect));        controlsRect = q->contentsRect();        viewportRect = QRect(controlsRect.topLeft(), controlsRect.bottomRight() - cornerOffset);    }    // If we have a corner widget and are only showing one scroll bar, we need to move it    // to make room for the corner widget.    if (hasCornerWidget && (needv || needh))        cornerOffset =  extPoint;#ifdef Q_WS_MAC    // Also move the scroll bars if they are covered by the native Mac size grip.    if (hasMacSizeGrip)        cornerOffset =  extPoint;#endif    // The corner point is where the scroll bar rects, the corner widget rect and the    // viewport rect meets.    const QPoint cornerPoint(controlsRect.bottomRight() + QPoint(1, 1) - cornerOffset);    // Some styles paints the corner if both scorllbars are showing and there is    // no corner widget. Also, on the Mac we paint if there is a native    // (transparent) sizegrip in the area where a corner widget would be.    if (needv && needh && hasCornerWidget == false#ifdef Q_WS_MAC        || ((needv || needh) && hasMacSizeGrip)#endif    ) {        cornerPaintingRect = QStyle::visualRect(opt.direction, opt.rect, QRect(cornerPoint, extSize));    } else {        cornerPaintingRect = QRect();    }#ifdef Q_WS_MAC    if (hasMacReverseSizeGrip)        reverseCornerPaintingRect = QRect(controlsRect.bottomRight() + QPoint(1, 1) - extPoint, extSize);    else        reverseCornerPaintingRect = QRect();#endif    if (needh) {        QRect horizontalScrollBarRect(QPoint(controlsRect.left(), cornerPoint.y()), QPoint(cornerPoint.x() - 1, controlsRect.bottom()));#ifdef Q_WS_MAC        if (hasMacReverseSizeGrip)            horizontalScrollBarRect.adjust(vsbExt, 0, 0, 0);#endif        scrollBarContainers[Qt::Horizontal]->setGeometry(QStyle::visualRect(opt.direction, opt.rect, horizontalScrollBarRect));        scrollBarContainers[Qt::Horizontal]->raise();    }    if (needv) {        const QRect verticalScrollBarRect  (QPoint(cornerPoint.x(), controlsRect.top()),  QPoint(controlsRect.right(), cornerPoint.y() - 1));        scrollBarContainers[Qt::Vertical]->setGeometry(QStyle::visualRect(opt.direction, opt.rect, verticalScrollBarRect));        scrollBarContainers[Qt::Vertical]->raise();    }    if (cornerWidget) {        const QRect cornerWidgetRect(cornerPoint, controlsRect.bottomRight());        cornerWidget->setGeometry(QStyle::visualRect(opt.direction, opt.rect, cornerWidgetRect));    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -