【发布时间】:2018-03-14 19:09:22
【问题描述】:
我在 QScrollArea 中放置自定义小部件时遇到了一些问题。我的自定义小部件在 QGridLayout 中包含 4 个标签来填充它。现在我想将此小部件保留在 QScrollArea 中并能够向其添加更多标签,但我希望其中只有 4 个显示在视口中。
这就是带有 4 个标签的小部件在 QScrollArea 中的样子:
这是添加两个标签后 QScrollArea 中的小部件,其中红色矩形是视口。
我怎样才能达到这样的效果?
====================================
更新
我最终用以下代码解决了我的问题。它可能需要一些小的间距修复。
#include "QtGuiApplication2.h"
#include "qscrollarea.h"
#include "CustomWidget.h"
QtGuiApplication2::QtGuiApplication2(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
QScrollArea * qScrollArea = new QScrollArea();
CustomWidget * customWidget = new CustomWidget(this);
qScrollArea->setWidget(customWidget);
qScrollArea->setWidgetResizable(true);
qScrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
ui.mainLayout->addWidget(qScrollArea, 1, 1, 1, 1);
}
CustomWidget 类:
#include "CustomWidget.h"
#include "qlabel.h"
CustomWidget::CustomWidget(QWidget *parent) : QWidget(parent)
{
labelsNum = 4;
rows = 2;
layout = new QGridLayout();
this->setLayout(layout);
QMargins * margin = new QMargins(10, 10, 10, 10);
layout->setContentsMargins(*margin);
layout->setHorizontalSpacing(5);
layout->setVerticalSpacing(5);
initLabels();
addLabels();
}
CustomWidget::~CustomWidget()
{
}
void CustomWidget::initLabels()
{
int cols = labelsNum / rows;
for (int i = 0; i < labelsNum; i++)
{
CustomLabel * label = new CustomLabel(this);
label->setText(QString::number(i));
label->setFrameShape(QFrame::Box);
labels.append(label);
}
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
layout->addWidget(labels.at(i * cols + j), i + 1, j + 1, 1, 1);
}
}
}
void CustomWidget::addLabels()
{
int numLabels = labels.size();
for (int i = 0; i < 2; i++)
{
CustomLabel * label = new CustomLabel(this);
label->setText(QString::number(numLabels + i));
label->setFrameShape(QFrame::Box);
labels.append(label);
}
labelsNum += rows;
int cols = labelsNum / rows;
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
layout->addWidget(labels.at(i * cols + j), i + 1, j + 1, 1, 1);
}
}
}
void CustomWidget::resizeEvent(QResizeEvent * e)
{
QWidget::resizeEvent(e);
QSize size = viewportSize;
//Substract all the spacing from view size
int horizontalSpacing = ((4 / rows) - 1) * layout->horizontalSpacing();
int verticalSpacing = (rows - 1) * layout->verticalSpacing();
size -= QSize(layout->margin() * 2 + horizontalSpacing, layout->margin() * 2 + verticalSpacing);
size *= 0.5;
for (int i = 0; i < labels.size(); i++)
{
labels.at(i)->resizeEvent(e, size);
}
}
以及自定义标签:
#include "CustomLabel.h"
CustomLabel::CustomLabel(QWidget *parent): QLabel(parent)
{
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
setMinimumSize(QSize(50, 50));
}
CustomLabel::~CustomLabel()
{
}
void CustomLabel::resizeEvent(QResizeEvent * e, QSize size)
{
this->setFixedSize(size);
}
【问题讨论】:
-
请出示您的代码
-
据我所知,您应该将标签放在布局中,然后放在小部件中,然后滚动区域设置小部件。
-
@Marco 是的,我就是这么做的。问题是当我放置超过 4 个时,当布局调整它们的大小时,它会在视口中显示所有这些。我希望它们都占用 1/4 的视口空间。
标签: c++ qt qt5 qscrollarea qlayout