
正文
Qt——QScrollArea
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
1.QScrollArea是否显示滚动条是由一个主要的子控件决定。
检查滚动条未显示
(1)是否只有一个子控件
(2)是否设置 setWidgetResizable(true);,因为这个的本质是QWidget大于QScrollArea
(3)子控件的大小是否合适。
2.如何在 QScrollArea中显示多个控件?
关键操作:
m_scrollArea->setWidgetResizable(true);
m_scrollArea->setWidget(m_widget);
构造一个 QWidget 作为 QScrollArea的唯一子控件
其他子控件作为 QWidget对象的子控件。
其中有两次布局,
QWidget 对 QScrollArea
others 对 QWidget
3.如何列表方式动态添加子控件到 QScrollArea
(1)动态添加
{
QVBoxLayout *layout = QVBoxLayout(this);
layout->addWidget(new pushbutton);
layout->addStretch(0); // 加弹簧
}
{
layout->insertWidget(0, new pushbutton); // 动态指定位置添加控件
}
(2)增删弹簧添加
{
QVBoxLayout *layout = QVBoxLayout(this);
m_spaceritem = new QSpacerItem(100, 200,
QSizePolicy::Expanding,
QSizePolicy::Expanding);
layout->addSpacerItem(m_spaceritem);
}
{
layout->removeItem(m_spaceritem);
layout->addWidget(new pushbutton);
layout->addSpacerItem(m_spaceritem);
}
4.如何实现网格动态增加?
QScrollArea的唯一子控件 QWidget 使用 QFlowLayout即可,
QFlowLayout实现
#ifndef QFLOWLAYOUT_H
#define QFLOWLAYOUT_H
#include <QLayout>
#include <QRect>
#include <QStyle>
class QFlowLayout : public QLayout
{
public:
, , );
, , );
~QFlowLayout();
void addItem(QLayoutItem *item) Q_DECL_OVERRIDE;
int horizontalSpacing() const;
int verticalSpacing() const;
Qt::Orientations expandingDirections() const Q_DECL_OVERRIDE;
bool hasHeightForWidth() const Q_DECL_OVERRIDE;
int heightForWidth(int) const Q_DECL_OVERRIDE;
int count() const Q_DECL_OVERRIDE;
QLayoutItem *itemAt(int index) const Q_DECL_OVERRIDE;
QSize minimumSize() const Q_DECL_OVERRIDE;
void setGeometry(const QRect &rect) Q_DECL_OVERRIDE;
QSize sizeHint() const Q_DECL_OVERRIDE;
QLayoutItem *takeAt(int index) Q_DECL_OVERRIDE;
private:
int doLayout(const QRect &rect, bool testOnly) const;
int smartSpacing(QStyle::PixelMetric pm) const;
private:
QList<QLayoutItem *> itemList;
int m_hSpace;
int m_vSpace;
};
#endif
#include <QWidget>
#include "QFlowLayout.h"
QFlowLayout::QFlowLayout(QWidget *parent, int margin, int hSpacing, int vSpacing)
: QLayout(parent),
m_hSpace(hSpacing),
m_vSpace(vSpacing)
{
setContentsMargins(margin, margin, margin, margin);
}
QFlowLayout::QFlowLayout(int margin, int hSpacing, int vSpacing)
: m_hSpace(hSpacing),
m_vSpace(vSpacing)
{
setContentsMargins(margin, margin, margin, margin);
}
QFlowLayout::~QFlowLayout()
{
QLayoutItem *item;
)))
delete item;
}
void QFlowLayout::addItem(QLayoutItem *item)
{
itemList.append(item);
}
int QFlowLayout::horizontalSpacing() const
{
) {
return m_hSpace;
}
else {
return smartSpacing(QStyle::PM_LayoutHorizontalSpacing);
}
}
int QFlowLayout::verticalSpacing() const
{
) {
return m_vSpace;
}
else {
return smartSpacing(QStyle::PM_LayoutVerticalSpacing);
}
}
int QFlowLayout::count() const
{
return itemList.size();
}
QLayoutItem *QFlowLayout::itemAt(int index) const
{
return itemList.value(index);
}
QLayoutItem *QFlowLayout::takeAt(int index)
{
&& index < itemList.size())
return itemList.takeAt(index);
else
;
}
Qt::Orientations QFlowLayout::expandingDirections() const
{
;
}
bool QFlowLayout::hasHeightForWidth() const
{
return true;
}
int QFlowLayout::heightForWidth(int width) const
{
, , width, ), true);
return height;
}
void QFlowLayout::setGeometry(const QRect &rect)
{
QLayout::setGeometry(rect);
doLayout(rect, false);
}
QSize QFlowLayout::sizeHint() const
{
return minimumSize();
}
QSize QFlowLayout::minimumSize() const
{
QSize size;
QLayoutItem *item;
foreach(item, itemList)
size = size.expandedTo(item->minimumSize());
size += QSize( * margin(), * margin());
return size;
}
int QFlowLayout::doLayout(const QRect &rect, bool testOnly) const
{
int left, top, right, bottom;
getContentsMargins(&left, &top, &right, &bottom);
QRect effectiveRect = rect.adjusted(+left, +top, -right, -bottom);
int x = effectiveRect.x();
int y = effectiveRect.y();
;
QLayoutItem *item;
foreach(item, itemList) {
QWidget *wid = item->widget();
int spaceX = horizontalSpacing();
)
spaceX = wid->style()->layoutSpacing(
QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal);
int spaceY = verticalSpacing();
)
spaceY = wid->style()->layoutSpacing(
QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Vertical);
int nextX = x + item->sizeHint().width() + spaceX;
) {
x = effectiveRect.x();
y = y + lineHeight + spaceY;
nextX = x + item->sizeHint().width() + spaceX;
lineHeight = ;
}
if (!testOnly)
item->setGeometry(QRect(QPoint(x, y), item->sizeHint()));
x = nextX;
lineHeight = qMax(lineHeight, item->sizeHint().height());
}
return y + lineHeight - rect.y() + bottom;
}
int QFlowLayout::smartSpacing(QStyle::PixelMetric pm) const
{
QObject *parent = this->parent();
if (!parent) {
;
}
else if (parent->isWidgetType()) {
QWidget *pw = static_cast<QWidget *>(parent);
, pw);
}
else {
return static_cast<QLayout *>(parent)->spacing();
}
}






