QT6 源(120):阅读与注释滚动容器 QScrollArea,给出本例的继承关系,源码,并给出一个具体的具体的模范使用案例

(1)本类的继承关系如下

在这里插入图片描述

(2)给出举例,以综合运用本类的成员函数

在这里插入图片描述

++

在这里插入图片描述

++对应上面举例的 ui_widget . h 头文件,这是最规范的代码

#ifndef UI_WIDGET_H
#define UI_WIDGET_H

#include <QtCore/QVariant>
#include <QtWidgets/QApplication>
#include <QtWidgets/QGridLayout>
#include <QtWidgets/QLabel>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QScrollArea>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QWidget>

QT_BEGIN_NAMESPACE

class Ui_Widget
{
public:
    QGridLayout * gridLayout;
    QScrollArea * scrollArea;
    QWidget     * scrollAreaWidgetContents; //本窗体归 QScrollArea所有 
    QVBoxLayout * verticalLayout;
    QPushButton * pushButton;
    QLabel      * label;

    void setupUi(QWidget * Widget)
    {
        if (Widget->objectName().isEmpty())
            Widget->setObjectName(QString::fromUtf8("Widget"));
        Widget->resize(291, 227);
        QFont font;
        font.setPointSize(14);
        Widget->setFont(font);                    //这是对主窗体的设置
        Widget->setContextMenuPolicy(Qt::CustomContextMenu);
       
        gridLayout = new QGridLayout(Widget);     //主窗体采用网格布局
        gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
        
        scrollArea = new QScrollArea(Widget);     //生成 QScrollArea对象
        scrollArea->setObjectName(QString::fromUtf8("scrollArea"));
        scrollArea->setWidgetResizable(true);
        
        scrollAreaWidgetContents = new QWidget(); //又一个 QWidget对象,并给其为垂直布局
        scrollAreaWidgetContents->setObjectName(QString::fromUtf8("scrollAreaWidgetContents"));
        scrollAreaWidgetContents->setGeometry(QRect(0, 0, 277, 213));
        verticalLayout = new QVBoxLayout(scrollAreaWidgetContents);
        verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));
        
        pushButton = new QPushButton(scrollAreaWidgetContents);  //按钮与标签都属于 scrollAreaWidgetContents窗体对象
        pushButton->setObjectName(QString::fromUtf8("pushButton"));
        verticalLayout->addWidget(pushButton);

        label = new QLabel(scrollAreaWidgetContents);
        label->setObjectName(QString::fromUtf8("label"));
        verticalLayout->addWidget(label);

        scrollArea->setWidget(scrollAreaWidgetContents); //QScrollArea吸纳了该 scrollAreaWidgetContents窗体为自己的窗体。

        gridLayout->addWidget(scrollArea, 0, 0, 1, 1);   //主窗体的网格布局接收了 QScrollArea

        retranslateUi(Widget);

        QMetaObject::connectSlotsByName(Widget);
    } // setupUi

    void retranslateUi(QWidget *Widget)
    {
        Widget    ->setWindowTitle(QCoreApplication::translate("Widget",   "H", nullptr));
        pushButton->setText(QCoreApplication::translate("Widget", "PushButton", nullptr));
        label     ->setText(QCoreApplication::translate("Widget", "TextLabel" , nullptr));
    } // retranslateUi

};

namespace Ui {
    class Widget: public Ui_Widget {};
} // namespace Ui

QT_END_NAMESPACE

#endif // UI_WIDGET_H

++以上代码演示了 QScrollArea 以及其成员函数 setWidget ( scrollAreaWidgetContents ) 的使用

(3)本源代码来自于头文件 qscrollarea . h

#ifndef QSCROLLAREA_H
#define QSCROLLAREA_H

#include <QtWidgets/qtwidgetsglobal.h>
#include <QtWidgets/qabstractscrollarea.h>

QT_REQUIRE_CONFIG(scrollarea);

QT_BEGIN_NAMESPACE

class QScrollAreaPrivate;

/*
The QScrollArea class provides a scrolling view onto another widget.

卷轴区域用于在框架内显示子小部件的内容。
如果小部件超过框架的大小,视图可以提供滚动条,以便可以查看子小部件的整个区域。
必须使用setWidget()指定子小部件。例如:
    QLabel * imageLabel = new QLabel;
    QImage   image( "happyguy.png" );
    imageLabel->setPixmap( QPixmap::fromImage(image) );

    scrollArea = new QScrollArea;
    scrollArea->setBackgroundRole( QPalette::Dark );
    scrollArea->setWidget( imageLabel );

上面的代码创建一个包含图像标签的滚动区域(如下图所示)。当缩放图像时,滚动区域可以提供必要的滚动条。
滚动条的外观取决于当前设置的滚动条策略。
您可以使用 QAbstractScrollArea的继承功能来控制滚动条的外观。
例如,您可以设置 QAbstractScrollArea::horizontalScrollBarPolicy和
               QAbstractScrollArea::verticalScrollBarPolicy属性。
或者,如果您希望当滚动区域的内容更改时,滚动条能够动态调整,
您可以使用 horizontalScrollBar()和verticalScrollBar()函数(这些函数允许您访问滚动条),
并在滚动区域的内容更改时使用 QScrollBar::setValue()函数设置滚动条值

//enum Qt::ScrollBarPolicy { ScrollBarAsNeeded, ScrollBarAlwaysOff, ScrollBarAlwaysOn }

您可以使用widget ()函数检索子小部件。可以使用setWidgetResizable()函数使视图可调整大小。
可以使用setAlignment()指定小部件的对齐方式。

两个方便函数ensureVisible ()和ensureWidgetVisible()通过必要时滚动内容来确保内容的一定区域在视口内可见。

Size Hints and Layouts:
在使用滚动区域显示自定义小部件的内容时,确保子小部件的大小提示设置为一个合适值非常重要。
如果使用标准 QWidget 作为子小部件,
可能需要调用 QWidget::etMinimumSize() 来确保小部件的内容在滚动区域中正确显示。

如果使用一个滚动区域来显示包含子控件的布局中的内容,那么重要的是要意识到布局的大小策略也会决定控件的大小。
如果你打算动态改变布局的内容,这一点尤其有用。
在这种情况下,将布局的大小约束属性设置为对布局的最小和/或最大大小提供约束的值
(例如QLayout::SetMinAndMaxSize),将使得每当布局的内容发生变化时,滚动区域的大小都会更新。

要查看使用 QScrollArea类的一个完整示例,请参见lmage Viewer示例。
该示例展示了如何将 QLabel和QScrollArea组合起来显示图像。

*/

class Q_WIDGETS_EXPORT QScrollArea : public QAbstractScrollArea
{
    Q_OBJECT

    //This property holds the alignment of the scroll area's widget.
    //By default, the widget stays rooted to the top-left corner of the scroll area.
    Q_PROPERTY(Qt::Alignment alignment READ alignment WRITE setAlignment)
    //Alignment = QFlags<AlignmentFlag>
    //enum Qt::AlignmentFlag{ ... AlignLeft, AlignRight, AlignTop, AlignBottom, ... };

    Q_PROPERTY(bool     widgetResizable   //大概是表示本 QScrollArea的大小是否被固定。
                READ    widgetResizable   WRITE   setWidgetResizable)
    //这个属性决定了滚动区域是否应该调整视图小部件的大小。
    //如果此属性设置为 false(默认值),则滚动区域将遵循其 Widget的大小。
    //无论此属性如何,您都可以使用 widget()->resize()以编程方式调整 widget的大小,
    //  滚动区域将自动将自身调整为新大小。
    //如果将此属性设置为true,则滚动区域将自动调整小部件的大小,以避免可以避免的滚动条,或利用额外空司。

private:
    Q_DECLARE_PRIVATE(QScrollArea)
    Q_DISABLE_COPY(QScrollArea)

protected:
    bool        event      (QEvent       *)           override;
    void  resizeEvent      (QResizeEvent *)           override;
    bool        eventFilter(QObject      *, QEvent *) override;

    void  scrollContentsBy(int dx, int dy) override;

    QSize viewportSizeHint() const override;

    QScrollArea(QScrollAreaPrivate & dd, QWidget * parent = nullptr);

public:
    //Constructs an empty scroll area with the given parent.
    explicit QScrollArea(QWidget * parent = nullptr);

    ~QScrollArea();


//   Q_PROPERTY(Qt::Alignment     alignment
//              READ              alignment    WRITE    setAlignment)
                Qt::Alignment     alignment() const;
                void           setAlignment(Qt::Alignment);


//   Q_PROPERTY(bool     widgetResizable   //大概是表示本 QScrollArea的大小是否被固定。
//              READ     widgetResizable   WRITE   setWidgetResizable)
                bool     widgetResizable() const;
                void  setWidgetResizable(bool resizable);

    //Returns the scroll area's widget, or nullptr if there is none.
    QWidget *      widget() const;
    void        setWidget(QWidget * widget); //Sets the scroll area's widget.
    //小部件成为滚动区域的子项,当滚动区域被删除或设置新的小部件时将被销毁。
    //小部件的autoFillBackground属性将被设置为true。
    //如果在添加小部件时卷轴区域可见,则必须显式显示它。
    //注意,您必须在调用此函数之前添加小部件的布局;
    //  如果您稍后添加它,则无论您何时显示滚动区域,小部件都不会可见。在这种情况下,您也无法稍后显示小部件。
    QWidget *  takeWidget();
    //Removes the scroll area's widget, and passes ownership of the widget to the caller.

    QSize sizeHint() const override;

    //Scrolls the contents of the scroll area so that the point (x, y) is visible inside the
    //  region of the viewport with margins specified in pixels by xmargin and ymargin.
    //If the specified point cannot be reached,
    //  the contents are scrolled to the nearest valid position.
    //The default value for both margins is 50 pixels.            //50像素,使某点可见
    void       ensureVisible(int x, int y,          int xmargin = 50, int ymargin = 50);
    void ensureWidgetVisible(QWidget * childWidget, int xmargin = 50, int ymargin = 50);
    //Scrolls the contents of the scroll area so that the         //使界面上的某个小部件可见。
    //  childWidget of QScrollArea::widget() is visible inside the
    //      viewport with margins specified in pixels by xmargin and ymargin.

    //Reimplements: QWidget::focusNextPrevChild(bool next).
    bool focusNextPrevChild(bool next) override;

}; //完结 class QScrollArea : public QAbstractScrollArea

QT_END_NAMESPACE

#endif // QSCROLLAREA_H

(4)

谢谢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值