(1)本类的继承关系如下:
(2)本源码来自于头文件 qabstractscrollarea . h :
#ifndef QABSTRACTSCROLLAREA_H
#define QABSTRACTSCROLLAREA_H
#include <QtWidgets/qtwidgetsglobal.h>
#include <QtWidgets/qframe.h>
QT_BEGIN_NAMESPACE
#if QT_CONFIG(scrollarea) //有此定义的
class QMargins;
class QScrollBar;
class QAbstractScrollAreaPrivate;
/*
The QAbstractScrollArea widget provides a scrolling area with on-demand scroll bars.
QAbstractScrollArea是滚动区域的低级抽象。
该区域提供了一个名为viewport的中心小部件。
该区域的内容将在viewport中滚动(即,内容的可见部分将在viewport中渲染)。
视口旁边是一个垂直滚动条,下面是一个水平滚动条。
当所有区域内容都适合于视图时,每个滚动条都可以可见或隐藏,具体取决于滚动条的Qt::ScrollBarPolicy。
当滚动条被隐藏时,视口会展开以覆盖所有可用的空间。
当滚动条再次可见时,视口会缩小以便为滚动条腾出空间。
可以预留一个视口周围的边距区域,见setViewportMargins()方法。
该功能主要用于在滚动区域上方或旁边放置 QHeaderView 控件。
QAbstractScrollArea的子类应实现边距。
当继承QAbstractScrollArea时,您需要执行以下操作:
通过设置滚动条的范围、值、页面步长并跟踪其移动来控制滚动条。
根据滚动条值在视口中绘制该区域的内容。
在viewportEvent()中处理视口接收的事件-特别是resize事件。
使用viewport->update()来更新viewport的内容,而不是使用update(),
因为所有绘图操作都发生在viewport上。
如果滚动条策略为Qt::ScrollBarAsNeeded(默认值),
QAbstractScrollArea将在滚动条提供非0滚动范围时显示滚动条,否则将隐藏滚动条。
当视口接收到resize事件或内容大小发生变化时,滚动条和视口应进行更新。
当滚动条值发生变化时,视口也需要进行更新。
滚动条的初始值通常在区域接收到新内容时设置。
我们举一个简单的例子,其中我们实现了一个可以滚动任何 QWidget 的滚动区域。
我们将该小部件设置为视口的一个子项;
这样,我们就不需要计算要绘制的小部件的哪一部分,而可以直接使用QWidget::move()函数移动小部件。
当区域内容或视口大小发生变化时,我们执行以下操作:
QSize areaSize = viewport()->size();
QSize widgetSize = widget->size();
verticalScrollBar ()->setPageStep(areaSize.height());
horizontalScrollBar()->setPageStep(areaSize.width() );
verticalScrollBar ()->setRange(0, widgetSize.height() - areaSize.height());
horizontalScrollBar()->setRange(0, widgetSize.width () - areaSize.width() );
updateWidgetPosition();
当滚动条改变值时,我们需要更新小部件的位置,即找到要在视口绘制的部分小部件:
int hvalue = horizontalScrollBar()->value();
int vvalue = verticalScrollBar() ->value();
QPoint topLeft = viewport()->rect().topLeft();
widget->move(topLeft.x() - hvalue, topLeft.y() - vvalue);
为了跟踪滚动条的移动,重新实现虚拟函数scrollContentsBy()。
为了微调滚动行为,连接到滚动条的QAbstractSlider::actionTriggered()信号,
并根据需要调整QAbstractSlider::sliderPosition。
为方便起见,QAbstractScrollArea使所有视口事件在虚拟视口Event()处理程序中可用。
当有意义时,将QWidget的专用处理程序重映射到视口事件。
重映射的专用处理程序包括:paintEvent()、mouseReleaseEvent()、mouseDoubleClickEvent(),
mouseMoveEventmousePressEvent()()wheelEvent、dragEnterEvent()、dragMoveEvent()、
dragLeaveEvent()、dropEvent()、contextMenuEvent()和resizeEvent()。
QScrollArea继承自 QAbstractScrollArea,
它为任何 QWidget(即,控件以像素为单位进行滚动)提供平滑滚动。
如果您需要更专门的行为,则只需继承 OAbstractScrollArea。
例如,如果区域中的所有内容不适合在 QWidget 上绘制,或者您不希望进行平滑滚动,则该情况为真。
*/
class Q_WIDGETS_EXPORT QAbstractScrollArea : public QFrame //文本框的父类
{
Q_OBJECT
//This property holds the policy for the horizontal scroll bar.
//The default policy is Qt::ScrollBarAsNeeded.
Q_PROPERTY(Qt::ScrollBarPolicy horizontalScrollBarPolicy //水平滚动条
READ horizontalScrollBarPolicy
WRITE setHorizontalScrollBarPolicy)
//This property holds the policy for the vertical scroll bar.
//The default policy is Qt::ScrollBarAsNeeded.
Q_PROPERTY(Qt::ScrollBarPolicy verticalScrollBarPolicy //垂直滚动条
READ verticalScrollBarPolicy
WRITE setVerticalScrollBarPolicy)
//此属性包含描述当视口大小变化时滚动区域大小如何变化的策略。
//默认策略是 OAbstractScrollArea::Adjustlgnored。更改此属性实际上可能会调整滚动区域的大小。
Q_PROPERTY(SizeAdjustPolicy sizeAdjustPolicy //大小调整策略
READ sizeAdjustPolicy
WRITE setSizeAdjustPolicy)
//This property holds the policy describing how the size of the
//scroll area changes when the size of the viewport changes.
//The default policy is QAbstractScrollArea::AdjustIgnored.
//Changing this property might actually resize the scrollarea.
private:
Q_DECLARE_PRIVATE(QAbstractScrollArea)
Q_DISABLE_COPY(QAbstractScrollArea)
Q_PRIVATE_SLOT(d_func(), void _q_hslide(int))
Q_PRIVATE_SLOT(d_func(), void _q_vslide(int))
Q_PRIVATE_SLOT(d_func(), void _q_showOrHideScrollBars())
friend class QStyleSheetStyle;
friend class QWidgetPrivate ;
protected:
//当通过 dx 和 dy 移动滚动条时,会调用这个虚拟处理程序,因此视口的内容应该相应地滚动。
//This virtual handler is called when the scroll bars are moved by dx, dy,
// and consequently the viewport's contents should be scrolled accordingly.
//默认实现只是对整个viewport()调用update()方法,
//子类可以重新实现此处理程序以进行优化,或者像QScrollArea一样移动内容控件。
//dx和dy参数是为了方便起见而存在的,这样,类就知道应该滚动多少(例如在像素移动时很有用)。
//你也可以忽略这些值,直接滚动到滚动条指示的位置。
//调用此函数以进行程序化滚动是错误的,请使用滚动条(例如通过直接调用QScrollBar::setValue))。
virtual void scrollContentsBy(int dx, int dy);
QAbstractScrollArea(QAbstractScrollAreaPrivate & dd, QWidget * parent = nullptr);
public:
explicit
QAbstractScrollArea(QWidget * parent = nullptr);
//Constructs a viewport.
//The parent argument is sent to the QWidget constructor.
~QAbstractScrollArea();
//Q_PROPERTY(Qt::ScrollBarPolicy horizontalScrollBarPolicy //水平滚动条
// READ horizontalScrollBarPolicy
// WRITE setHorizontalScrollBarPolicy)
Qt::ScrollBarPolicy horizontalScrollBarPolicy() const;
void setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy);
//Q_PROPERTY(Qt::ScrollBarPolicy verticalScrollBarPolicy //垂直滚动条
// READ verticalScrollBarPolicy
// WRITE setVerticalScrollBarPolicy)
Qt::ScrollBarPolicy verticalScrollBarPolicy() const;
void setVerticalScrollBarPolicy(Qt::ScrollBarPolicy);
enum SizeAdjustPolicy {
AdjustIgnored ,
//The scroll area will behave like before - and not do any adjust.
AdjustToContentsOnFirstShow,
//The scroll area will adjust to its viewport the first time it is shown.
AdjustToContents
//The scroll area will always adjust to the viewport
};
Q_ENUM( SizeAdjustPolicy )
//Q_PROPERTY(SizeAdjustPolicy sizeAdjustPolicy //大小调整策略
// READ sizeAdjustPolicy
// WRITE setSizeAdjustPolicy)
SizeAdjustPolicy sizeAdjustPolicy() const;
void setSizeAdjustPolicy(SizeAdjustPolicy policy);
//Returns the horizontal scroll bar.
QScrollBar * horizontalScrollBar() const;
void setHorizontalScrollBar(QScrollBar * scrollbar);
//用滚动条 scrollbar替换现有的水平滚动条,并在新滚动条上设置前一个滚动条的所有滑块属性。
// 然后删除前一个滚动条。默认情况下,QAbstractScrollArea已经提供了水平和垂直滚动条。
//您可以调用这个函数,用您自己的自定义滚动条替换默认的水平滚动条。
//Returns the vertical scroll bar.
QScrollBar * verticalScrollBar() const;
void setVerticalScrollBar (QScrollBar * scrollbar);
//Replaces the existing vertical scroll bar with scrollBar,
//and sets all the former scroll bar's slider properties on the new scroll bar.
//The former scroll bar is then deleted.
//QAbstractScrollArea already provides vertical and
// horizontal scroll bars by default.
//You can call this function to replace the
// default vertical scroll bar with your own custom scroll bar.
//Returns a list of the currently set scroll bar widgets.
//alignment can be any combination of the four location flags.
// QWidgetList = QList<QWidget *>
QWidgetList scrollBarWidgets(Qt::Alignment alignment);
void addScrollBarWidget(QWidget * widget, Qt::Alignment alignment);
//在对齐方式 alignment指定的位置将小部件 widget添加为滚动条小部件。
//滚动条小部件显示在水平或垂直滚动条的旁边,并且可以放置在滚动条的两侧。
//如果希望滚动条小部件始终可见,请将相应滚动条的scrollBarPolicy设置为AlwaysOn。
//对齐 alignment必须是映射到水平滚动条的Qt::Alignleft和Ot::AlignRight之一,
// 或者映射到垂直滚动条的Qt::AlignTop和Qt::AlignBottom之-.
//滚动条窗口小部件可以通过重新设置窗口小部件的父级或删除窗口小部件来删除。
//使用OWidget::hide()也可以隐藏一个widget.
//滚动条小部件的大小将调整到适合当前样式的滚动条几何形状。
//以下描述了水平滚动条上滚动条小部件的情况:
//小部件的高度将被设置为与滚动条的高度相匹配。
//要控制widget的宽度,可以使用QWidget::setMinimumWidth和QWidget::setMaximumWidth,
//或者实现QWidget::sizeHint()并设置水平大小策略。
//如果您想要一个方形小部件,
//请调用 QStyle::pixelMetric(Q_Style::PMScrollBarExtent)并将宽度设置为此值。
//Returns the widget in the corner between the two scroll bars.
//By default, no corner widget is present.
QWidget * cornerWidget() const;
void setCornerWidget(QWidget * widget);
//Sets the widget in the corner between the two scroll bars to be widget.
//您可能还想将至少一种滚动条模式设置为AlwaysOn。
//传递nullptr表示角落的控件为空。 之前的任何角落小部件都被隐藏了。
//您可以在不同时间使用相同的widget调用setCornerWidget()方法。
//这里设置的所有小部件将在滚动区域被销毁时删除,
// 除非您在设置其他角落小部件(或nullptr)后单独表示该小部件。
// unless you separately reparent the widget after setting some other
// corner widget (or nullptr)
//任何新设置的控件都不应有当前父级。 默认情况下,没有角落小部件。
QSize sizeHint() const override;
QSize minimumSizeHint() const override;
//返回视口小部件。使用 QScrollArea::widget()函数来检索视口窗体的内容。
QWidget * viewport() const;
void setViewport( QWidget * widget);
//Sets the viewport to be the given widget.
//The QAbstractScrollArea will take ownership of the given widget.
//If widget is nullptr,
//QAbstractScrollArea will assign a new QWidget instance for the viewport.
//This slot is called by QAbstractScrollArea after setViewport(viewport) has
// been called. Reimplement this function in a subclass
// of QAbstractScrollArea to initialize the new viewport before it is used.
virtual void setupViewport( QWidget * viewport); //这是个虚函数
QSize maximumViewportSize() const;
//Returns the size of the viewport as if the
// scroll bars had no valid scrolling range.
protected:
//返回视口的建议大小。默认实现返回视口()->sizeHint()。
virtual //请注意,大小只是视口的大小,不包括任何可见的滚动条。
QSize viewportSizeHint() const;
//Returns the margins around the scrolling area.
//By default all the margins are zero.
QMargins viewportMargins() const;
//Sets margins around the scrolling area.
void setViewportMargins(const QMargins & margins);
void setViewportMargins(int left, int top, int right, int bottom);
//Sets the margins around the scrolling area to left, top, right and bottom.
//这对于具有“锁定”行和列的电子表格等应用程序非常有用。边距空间留空;将小部件放在未使用的区域。
//请注意,此函数经常被QTreeView和QTableView调用,因此边距必须由QAbstractScrollArea子类实现。
//此外,如果要在项目视图中使用子类,则它们不应调用此函数。 默认情况下,所有页边距均为零。
virtual bool viewportEvent(QEvent *);
bool eventFilter (QObject *, QEvent *) override;
bool event(QEvent *) override;
void resizeEvent(QResizeEvent *) override;
void paintEvent(QPaintEvent *) override;
void mousePressEvent(QMouseEvent *) override;
void mouseReleaseEvent(QMouseEvent *) override;
void mouseDoubleClickEvent(QMouseEvent *) override;
void mouseMoveEvent(QMouseEvent *) override;
void wheelEvent(QWheelEvent *) override;
void contextMenuEvent(QContextMenuEvent *) override;
void dragEnterEvent(QDragEnterEvent *) override;
void dragMoveEvent(QDragMoveEvent *) override;
void dragLeaveEvent(QDragLeaveEvent *) override;
void dropEvent(QDropEvent *) override;
void keyPressEvent(QKeyEvent *) override;
}; //完结 class QAbstractScrollArea : public QFrame
#endif // QT_CONFIG(scrollarea)
QT_END_NAMESPACE
#endif // QABSTRACTSCROLLAREA_H
(3)
谢谢